UE4 C++里使用DXVA解码视频出现问题
本帖最后由 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;
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, ctx->tmp_frame->linesize,
(uint8_t*)LockedRect.pBits,
LockedRect.Pitch, frame->width, frame->height);
av_image_copy_plane(ctx->tmp_frame->data, ctx->tmp_frame->linesize,
(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上也行~{:2_28:}
----------------------------------------------------------------------
问题已经解决了~
原因其实不在这,还是解码完成后 释放内存的操作有问题,内存占用这么多是正常的,今天来论坛看看突然想起这个帖子,就上来改一下。
https://github.com/Ehamloptiran/TextureMoviePlugin
https://forums.unrealengine.com/development-discussion/engine-source-github/3775-project-fluidsurface-plugin/page16 https://msdn.microsoft.com/en-us/library/windows/desktop/ff476428(v=vs.85).aspx
https://stackoverflow.com/questions/35239204/directx-11-compute-shader-copy-data-from-the-gpu-to-the-cpu
https://stackoverflow.com/questions/15814211/when-is-the-data-copied-to-gpu-memory
http://xboxforums.create.msdn.com/forums/p/22525/120357.aspx#120357 本帖最后由 mknmknmk 于 2017-11-11 22:15 编辑
设置rendertarget你的视频解码填充rendertarget 数据 , 将rendertarget 作为一个材质的贴图, 将材质赋予模型。
https://answers.unrealengine.com/questions/252653/draw-on-render-target-texture.html
本帖最后由 mknmknmk 于 2017-11-11 22:12 编辑
https://answers.unrealengine.com/questions/288012/is-it-possible-to-create-textures-dynamically.html
https://msdn.microsoft.com/en-us/library/windows/desktop/ee418784(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/mt613239(v=vs.85).aspx
https://docs.unrealengine.com/latest/INT/Engine/Rendering/RenderTargets/BlueprintRenderTargets/HowTo/CreatingTextures/
mknmknmk 发表于 2017-11-11 21:57
https://answers.unrealengine.com/questions/288012/is-it-possible-to-create-textures-dynamically.html ...
谢谢咯~ 我先看看这些{:2_27:} 大佬,我需要在游戏中录制视频,可以保存在本地为mp4,大佬有了解过吗 妄想症丶 发表于 2018-4-19 22:15
大佬,我需要在游戏中录制视频,可以保存在本地为mp4,大佬有了解过吗
这个不清楚。。我只做播放功能。
页:
[1]