UE4 C++里使用DXVA解码视频出现问题

[复制链接]
查看3839 | 回复5 | 2017-11-11 14:20:38 | 显示全部楼层 |阅读模式
本帖最后由 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上也行~

----------------------------------------------------------------------
问题已经解决了~
原因其实不在这,还是解码完成后 释放内存的操作有问题,内存占用这么多是正常的,今天来论坛看看突然想起这个帖子,就上来改一下。



mknmknmk | 2017-11-11 21:41:20 | 显示全部楼层
https://github.com/Ehamloptiran/TextureMoviePlugin
https://forums.unrealengine.com/development-discussion/engine-source-github/3775-project-fluidsurface-plugin/page16
回复 支持 反对

使用道具 举报

mknmknmk | 2017-11-11 21:50:30 | 显示全部楼层
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 21:54:37 | 显示全部楼层
本帖最后由 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 21:57:22 | 显示全部楼层
本帖最后由 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/



回复 支持 反对

使用道具 举报

fuliangjun | 2017-11-12 11:49:02 | 显示全部楼层
mknmknmk 发表于 2017-11-11 21:57
https://answers.unrealengine.com/questions/288012/is-it-possible-to-create-textures-dynamically.html ...

谢谢咯~ 我先看看这些
回复 支持 反对

使用道具 举报

妄想症丶 | 2018-4-19 22:15:31 | 显示全部楼层
大佬,我需要在游戏中录制视频,可以保存在本地为mp4,大佬有了解过吗
回复 支持 反对

使用道具 举报

fuliangjun | 2018-4-23 10:58:08 | 显示全部楼层
妄想症丶 发表于 2018-4-19 22:15
大佬,我需要在游戏中录制视频,可以保存在本地为mp4,大佬有了解过吗

这个不清楚。。我只做播放功能。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

4

主题

20

回帖

1494

积分

中阶编码师

积分
1494