FFMPEG RGB至YUV420P:警告:数据未对齐!这会导致速度损失

时间:2019-01-24 01:58:23

标签: ffmpeg

我正在尝试将标准RGB颜色空间转换为YUV420P。我正在努力弄清楚为什么我会不断收到“警告:数据未对齐!在执行代码时,这可能导致“速度损失”。我看了很多例子。

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);
}

2 个答案:

答案 0 :(得分:0)

我希望它能对您有所帮助。 我正在将YUV444解码的帧转换为RGBA格式。

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);

答案 1 :(得分: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;
}