使用ffmpeg将YV12转换成RGB

看了下FFMPEG的pixfmt,没有YV12的格式

然后使用YUV420P(即I420)的方式去转换,发现颜色明显不对

看了下YV12和YUV420P的区别

只是U分量和V分量存储方式对换而已


现在要转换YV12为RGB24的话,我可以先将YV12->YUV420P

就是将YV12的数据的Y分量、U分量和V分量分别存到新YUV420P的Y分量、U分量和V分量处


YV12:

YY                                                               

YY                            

V

U


YUV420P:

YY

YY

U

V


关于YV12和NV12的格式说明可以看看别人的 http://blog.sina.com.cn/s/blog_784448d601015fiv.html

以及http://blog.csdn.net/leixiaohua1020/article/details/12234821

提供简单例子如下

static void CopyDataFromYV12ToYUV420P(uint8_t* pDst, const uint8_t* pSrc, int nWidth, int nHeight)
{
    int nYSize = nWidth * nHeight;
    int nVSize = nYSize / 4;
    int nUSize = nYSize / 4;
 
 
    int nSrcUOffset = nYSize;
    int nSrcVOffset = nSrcUOffset + nUSize;
 
 
    int nDstVOffset = nYSize;
    int nDstUOffset = nDstVOffset + nVSize;
    memcpy(pDst, pSrc, nYSize);
    memcpy((void*)((int)pDst + nDstVOffset), (void*)((int)pSrc + nSrcVOffset), nVSize);
    memcpy((void*)((int)pDst + nDstUOffset), (void*)((int)pSrc + nSrcUOffset), nUSize);
}

void GetRGB888FromYV12(const char* pYV12, const int nWidthIn, const int nHeightIn, \
                       char** pBufferOut, const int nWidthOut, const int nHeightOut)
{
    SwsContext* pConvert_ctx = NULL;
    AVFrame* pFrameIn = NULL;
    AVFrame* pFrameOut = NULL;
    uint8_t* pFrameBufferOut = NULL;
    int nFrameOutBufferSize = 0;
    uint8_t* pBufferIn = NULL;
    int nFrameInBufferSize = 0;
 
 
 
 
    pFrameIn = avcodec_alloc_frame();
    nFrameInBufferSize = avpicture_get_size(AV_PIX_FMT_YUV420P, nWidthIn, nHeightIn);
    pBufferIn = (uint8_t*)av_malloc(nFrameInBufferSize * sizeof(uint8_t));
    CopyDataFromYV12ToYUV420P(pBufferIn, (const uint8_t*)pYV12, nWidthIn, nHeightIn);
    avpicture_fill((AVPicture*)pFrameIn, (uint8_t*)pBufferIn, AV_PIX_FMT_YUV420P, nWidthIn, nHeightIn);
 
 
    pFrameOut = avcodec_alloc_frame();
    nFrameOutBufferSize = avpicture_get_size(PIX_FMT_RGB24, nWidthOut, nHeightOut);
    pFrameBufferOut = (uint8_t*)av_malloc(nFrameOutBufferSize * sizeof(uint8_t));
    avpicture_fill((AVPicture*)pFrameOut, pFrameBufferOut, PIX_FMT_RGB24, nWidthOut, nHeightOut);
 
 
    pConvert_ctx = sws_getContext(nWidthIn, nHeightIn, AV_PIX_FMT_YUV420P, \
                                   nWidthOut, nHeightOut, PIX_FMT_RGB24, \
                                  SWS_BICUBIC, NULL, NULL, NULL);
    sws_scale(pConvert_ctx, (const uint8_t* const*)pFrameIn->data, pFrameIn->linesize, 0,\
              nHeightIn, pFrameOut->data, pFrameOut->linesize);
    *pBufferOut = (char*)pFrameBufferOut;
 
 
    av_free(pBufferIn);
    av_free(pFrameOut);
    sws_freeContext(pConvert_ctx);
}


你可能感兴趣的:(使用ffmpeg将YV12转换成RGB)