本帖最后由 fuliangjun 于 2017-12-16 23:06 编辑
最近在做FFMPEG硬解码的一些东西的时候遇到了一个问题:
我在GPU解码完之后,在dxva2_retrieve_data里把解码后的数据取回CPU,开始刚弄完的时候运行都没问题,可是我把视频解码改成在线程里运行,然后创建了很多个线程同时解码多个视频时,就遇到问题了。
每多创建一个线程解码视频,应用程序的占用内存就会增加一点,开了大概30个线程的时候,占用的内存就达到了4G(每个视频解码的分辨率都调得很低,大概128*128左右)
然后最大的问题是 视频解码完以后把该释放的变量都释放了,然后关闭线程,内存不会释放!
然后继续加线程解码,内存就会不停的增加。。。(解码的过程中内存不会有很大变化,没有出现边解码边加内存的情况),下面是我dxva2_retrieve_data函数
static int dxva2_retrieve_data(AVCodecContext *s, AVFrame *frame)
{
LPDIRECT3DSURFACE9 surface = (LPDIRECT3DSURFACE9)frame->data[3];
InputStream *ist = (InputStream *)s->opaque;
DXVA2Context *ctx = (DXVA2Context *)ist->hwaccel_ctx;
D3DSURFACE_DESC surfaceDesc;
D3DLOCKED_RECT LockedRect;
HRESULT hr;
int ret;
IDirect3DSurface9_GetDesc(surface, &surfaceDesc);
ctx->tmp_frame->width = frame->width;
ctx->tmp_frame->height = frame->height;
ctx->tmp_frame->format = AV_PIX_FMT_NV12;
ret = av_frame_get_buffer(ctx->tmp_frame, 32);
if (ret < 0)
return ret;
//*param Pointer to a D3DLOCKED_RECT structure that describes the locked region.
//*param Pointer to a rectangle to lock. Specified by a pointer to a RECT structure. Specifying NULL for this parameter expands the dirty region to cover the entire surface.
hr = surface->LockRect(&LockedRect, NULL, D3DLOCK_READONLY);//获取指向surface存储区的指针,调试过程中发现执行了这一步 就会出现占用内存增加而且不释放的问题
if (FAILED(hr)) {
av_log(NULL, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n");
return AVERROR_UNKNOWN;
}
av_image_copy_plane(ctx->tmp_frame->data[0], ctx->tmp_frame->linesize[0],
(uint8_t*)LockedRect.pBits,
LockedRect.Pitch, frame->width, frame->height);
av_image_copy_plane(ctx->tmp_frame->data[1], ctx->tmp_frame->linesize[1],
(uint8_t*)LockedRect.pBits + LockedRect.Pitch * surfaceDesc.Height,
LockedRect.Pitch, frame->width, frame->height / 2);
surface->UnlockRect();
ret = av_frame_copy_props(ctx->tmp_frame, frame);
if (ret < 0)
goto fail;
av_frame_unref(frame);
av_frame_move_ref(frame, ctx->tmp_frame);
return 0;
fail:
av_frame_unref(ctx->tmp_frame);
return ret;
}
并且,我如果改成软解码的话,就不会有内存的问题,而且我调试之后发现 : 就是执行 LockRect 的时候 内存才开始加的。
我是最近才接触视频解码的东西,对DXVA和FFMPEG都还不是很熟,求大佬帮忙~
如果不能解决的话,能给个有效的从GPU取回数据的方法或者教我直接把解码后的图渲染到UE的Texture2d上也行~
----------------------------------------------------------------------
问题已经解决了~
原因其实不在这,还是解码完成后 释放内存的操作有问题,内存占用这么多是正常的,今天来论坛看看突然想起这个帖子,就上来改一下。
|