看了下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);
}