如何将ffmpeg解码出来的yuv420数据拷贝到自己申请的yuv内存中?

Go和分布式IM 2014-07-31 02:48:45
大家好,在使用ffmpeg的时候,由于在一些低配置的机器上测试视频输出,发现性能不足,所以将解码和渲染分开了,解码使用单独的线程,渲染使用单独的线程,解码完成的YUV数据,放入到自己的队列中,渲染线程循环取YUV数据,并交给显示器。

但是由于对YUV420的不熟悉,所以不知道如何拷贝:我的代码如下,但是播放的视频不对,放几次后出现异常


BOOL CLibAvNormalDraw::Draw(HWND hWnd,BYTE * pY,BYTE * pU,BYTE * pV,int yWrap,int uWrap,int vWrap)
{
if(!threadIsRun)
g_event.SetEvent();

BYTE * dataY;
BYTE * dataU;
BYTE * dataV;

int i = 0;
int width = m_bDraw.Width(),height = m_bDraw.Height();
int height_half = height / 2, width_half = width / 2;

dataY = new BYTE[width * height];
dataU = new BYTE[width / 2 * height /2];
dataV = new BYTE[width / 2 * height /2];

//下面注释的代码是在网上找的,但是不对,执行到framesQ.push(av);就异常
////copy y
//for (i = 0; i < height; i++)
// memcpy(dataY + i * yWrap , pY + i * yWrap , width);
////copy u
//for (i = 0; i < height_half; i++)
// memcpy(dataU +i * uWrap , pU + i * uWrap , width_half);
////copy v
//for (i = 0; i < height_half; i++)
// memcpy(dataV + i * vWrap , pV + i * vWrap, width_half);

//这个也会出现异常
/*for (i=0; i<height; i++)
{
memcpy(dataY,pY + i * yWrap, width);
}
for (i=0; i<height_half; i++)
{
memcpy(dataU,pU + i * uWrap, width_half);
}
for (i=0; i<height_half; i++)
{
memcpy(dataV,pV + i * vWrap, width_half);
}*/

//拷贝YUV420数据到另外一个位置,这里前面可以播放大约1秒左右,然后就出现异常了
memcpy(dataY,pY,width * height);
memcpy(dataU,pU,width_half*height_half);
memcpy(dataV,pV,width_half*height_half);

AVFrameEx av;
av.outPutHWnd = hWnd;
av.pdataY = dataY;
av.pdataU = dataU;
av.pdataV = dataV;
mutex.Lock();
//加入到queue带渲染队列中
framesQ.push(av);
mutex.UnLock();

return true;
}


求好心人帮帮忙,实在不知道怎么做了。原来的做法是
直接

AVFrameEx av;
av.outPutHWnd = hWnd;
av.pdataY = dataY;
av.pdataU = dataU;
av.pdataV = dataV;
mutex.Lock();
//加入到queue带渲染队列中
framesQ.push(av);
mutex.UnLock();
,这种没问题,但是机器性能不够,播放720*1080P,因为屏幕是1920*1080的分辨率,所以输出的时候拉伸过,会有很明显的画面撕裂,怀疑是解码过快,在显示器渲染的时候,把该数据给覆盖了,导致的。
...全文
635 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
Go和分布式IM 2014-08-01
  • 打赏
  • 举报
回复
自问自答。。 虽然网上的方法都试了,但是也没找到合适的参考方案。只能对 解码和渲染的线程进行同步控制了(ffmpeg自己的缓冲区,解码后估计会把前一次的数据给覆盖,因为测试机的配置和性能的问题,渲染720*1080视频的时候,需要做拉伸处理,估计耗费了很多时间,所以解码要比渲染块,即渲染某一帧的时候,实际上数据已经改变了,就出现了画面撕裂的问题)。 不过终极的方案是:改变渲染方式,由软件渲染改为硬件渲染,比如DirextShow等。

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧