4

I am trying to convert a standard RGB color space to YUV420P. I am struggling to figure out why I keep getting 'Warning: data is not aligned! This can lead to a speedloss' when executing the code. I have looked at a multitude of examples.

int ImageDecoder::rgb2yuv(uint8_t *src, 
                          uint8_t *dest, 
                          uint32_t width, 
                          uint32_t height)
{
    struct SwsContext *imgCtx = NULL;
    AVFrame *pFrameYUV;
    enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_RGB24;
    enum AVPixelFormat dst_pix_fmt = AV_PIX_FMT_YUV420P;
    int ret;
    int size;
    const int RGBLinesize[1] = { 3 * (int)width };

    pFrameYUV = av_frame_alloc();
    pFrameYUV->width = width;
    pFrameYUV->height = height;
    pFrameYUV->format = dst_pix_fmt;

    // Initialize pFrameYUV linesize
    ret = av_image_alloc(pFrameYUV->data, pFrameYUV->linesize, pFrameYUV->width, pFrameYUV->height, AV_PIX_FMT_YUV420P, 1);
    getLogger()->info("ImageDecoder:{} width={} height={} linesize[0]={} linesize[1]={} linesize[2]={}", 
        __func__, pFrameYUV->width, pFrameYUV->height, pFrameYUV->linesize[0], pFrameYUV->linesize[1], pFrameYUV->linesize[2]);
    size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pFrameYUV->width, pFrameYUV->height, 1);

    imgCtx = sws_getCachedContext(imgCtx,
                                  width, 
                                  height,
                                  AV_PIX_FMT_RGB24,
                                  pFrameYUV->width, 
                                  pFrameYUV->height,
                                  AV_PIX_FMT_YUV420P,
                                  SWS_BICUBIC, 0, 0, 0);

    if( imgCtx == NULL)
    {
        getLogger()->error("ERROR: ImageDecoder: {} Cannot initialize the conversion context", __func__);
    }

   sws_scale(imgCtx,
             (const uint8_t* const*)&src,
             RGBLinesize,
             0, 
             height, 
             pFrameYUV->data, 
             pFrameYUV->linesize);

    memcpy(dest, &pFrameYUV->data[0], size);

    sws_freeContext(imgCtx);
    av_free(pFrameYUV);
}
weegz
  • 51
  • 1
  • 3

2 Answers2

0

I hope it helps you. I am converting YUV444 decoded frames to RGBA format.

AVFrame* RGBFrame = av_frame_alloc();

RGBFrame->width = YUV_frame->width;     RGBFrame->format = AV_PIX_FMT_RGBA;
RGBFrame->height = YUV_frame->height;

int ret = av_image_alloc(RGBFrame->data, RGBFrame->linesize, RGBFrame->width, RGBFrame->height, AV_PIX_FMT_RGBA, YUV_frame->pict_type);
if (ret < 0)
    return false;

SwsContext* sws_Context = NULL;
sws_Context = sws_getCachedContext(sws_Context, YUV_frame->width, YUV_frame->height, pVideoCodecCtx->pix_fmt,
    YUV_frame->width, YUV_frame->height, AV_PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL);
if (sws_Context == NULL) return false;

int result = sws_scale(sws_Context, YUV_frame->data, YUV_frame->linesize, 0, (int)YUV_frame->height, RGBFrame->data, RGBFrame->linesize);
if (result < 0)     return false;

if (RGBFrame == NULL) {
    av_frame_unref(RGBFrame);
    return false;
}

sws_freeContext(sws_Context);
Birds
  • 65
  • 2
  • 13
0
int ImageDecoder::rgb2yuv(uint8_t *src,
                      uint8_t *dest,
                      uint32_t *outBufferSize,
                      uint32_t width,
                      uint32_t height)
{
    struct SwsContext *imgCtx = NULL;

    uint8_t * RGBData[1] = {src};
    const int RGBLinesize[1] = {3 * (int) width};

    uint8_t * YUVData[] = {dest,
                           YUVData[0] + ((int) width * (int) height),
                           YUVData[1] + (((int) width * (int) height) / 4)};
    const int YUVLinesize[] = {(int) width, (int) width / 2, (int) width / 2};

    int size;

    size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, width, height, 1);
    *outBufferSize = size;

    imgCtx = sws_getCachedContext(imgCtx,
                                  width,
                                  height,
                                  AV_PIX_FMT_RGB24,
                                  width,
                                  height,
                                  AV_PIX_FMT_YUV420P,
                                  SWS_BICUBIC, 0, 0, 0);
    if (imgCtx == NULL)
    {
        getLogger()->error("ERROR: ImageDecoder: {} Cannot initialize the conversion context", __func__);
        return -1;
    }

    sws_scale(imgCtx,
              RGBData,
              RGBLinesize,
              0,
              height,
              YUVData,
              YUVLinesize);

    sws_freeContext(imgCtx);

    return 0;
}
weegz
  • 51
  • 1
  • 3
  • This code works as the image has successfully been converted to a YUV420P color space. However, still getting the misalignment warning. – weegz Jan 28 '19 at 19:22