ffmpeg dxva2硬件解码+opengl显示

lzg0610210238 2017-09-04 03:38:44
背景:
最近一直在忙ffmpeg利用dxva2硬件解码后利用opengl glsl绘图显示,目前存在以下问题,希望能有人能帮忙解答给出思路。
问题:
硬解码后数据拷贝回内存耗时过长导致播放很慢,原来9分钟的4K视频,需要耗时12分钟才能播完。
目前的实现方式:
1)开启2个线程分别用于ffmpeg解码视频、opengl绘图。
2)ffmpeg解码视频线程中启用dxva2在gpu(Intel HD5500 + AMD)中解码转换为NV12格式。
3)将解码后的NV12格式数据从gpu拷贝回内存中。

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;

hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, D3DLOCK_READONLY);
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);

IDirect3DSurface9_UnlockRect(surface);

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;
}

4)opengl绘图线程中通过glsl shader中将NV12转换为bgr格式显示。

想知道经验人士在这一块是如何处理的?给点建议?


...全文
4514 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
MouseMedia 2019-11-26
  • 打赏
  • 举报
回复
理论上,GPU解码后得数据,应该直接显示出去,而不应该copy回cpu.
F_Reading 2018-12-26
  • 打赏
  • 举报
回复
引用 5 楼 lzg0610210238 的回复:
最终是通过SSE4指令集从GPu中快速拷贝内容到CPU中解决了该问题。
你好,能交流下吗
lzg0610210238 2018-05-08
  • 打赏
  • 举报
回复
引用 4 楼 cjdxzy2007 的回复:
这种copy-back的方式来处理高帧率、高分辨率的解码,性能可定会存在瓶颈。 应该用native的方式,或者cuvid硬解方案吧
请问native的方式具体是指什么?cuvid硬解方案最终还是需要把内容拷贝回CPU吧?能直接将解码的数据在GPU中绘制不经过cpu?
lzg0610210238 2018-05-04
  • 打赏
  • 举报
回复
最终是通过SSE4指令集从GPu中快速拷贝内容到CPU中解决了该问题。
cjdxzy2007 2018-03-07
  • 打赏
  • 举报
回复
这种copy-back的方式来处理高帧率、高分辨率的解码,性能可定会存在瓶颈。 应该用native的方式,或者cuvid硬解方案吧
百灵工作室 2018-01-10
  • 打赏
  • 举报
回复
HD系列显卡是intel的CPU核显,怎么来个AMD呢? 如果用HD5500做硬解码,windows下是dxva2,解码后的NV12数据是在内存划给核显的那部分,无需拷贝(在surface上),但是不一定是连续的,如果不做他用,只做显示,可以直接通过核显去显示,也不需要转换到bgr格式,即便转换,也不一定要转成bgr,可以显示yuv420P,那么你只需要处理uv交错就可以了
  • 打赏
  • 举报
回复
想问这个问题后来怎么处理的 能否共享下
饭特稀特别稀 2017-10-10
  • 打赏
  • 举报
回复
从GPU拷贝出来数据,这一步完全没必要,如果这样做的话,还不如不做硬解码。

579

社区成员

发帖
与我相关
我的任务
社区描述
CUDA™是一种由NVIDIA推出的通用并行计算架构,该架构使GPU能够解决复杂的计算问题。 它包含了CUDA指令集架构(ISA)以及GPU内部的并行计算引擎。
社区管理员
  • CUDA编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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