WPF视频渲染系列

第一章 使用HwndHost渲染视频
第二章 使用d3d渲染视频
第三章 使用d3d渲染dxva2数据(本章)
第四章 使用WriteableBitmap渲染视频


文章目录

  • WPF视频渲染系列
  • 前言
  • 一、对象说明
    • 1.dxva2解码Surface
    • 2.D3DImage
  • 二、如何实现?
    • 1.创建RT Texture
    • 2.设置D3DImage缓存
    • 3.关联界面
    • 4.渲染
  • 三、示例代码
  • 四、效果预览
  • 五、性能对比
  • 总结
  • 附录
    • 1、C#操作d3d对象的库

前言

使用dxva2解码渲染的方案是有的,通过窗口句柄关联d3d对象的方式直接渲染,性能相当好,但是在wpf中显然不太合适,嵌入hwnd窗口与wpf绘制不兼容,而且对于键盘事件也会有影响,最好的方式还是使用d3d渲染,本文主要讲述如何将dxva2解码的数据不经过转换,直接渲染到wpf的image上。


一、对象说明

1.dxva2解码Surface

对于dxva2解码,以ffmpeg使用dxva2为例,解码后的数据放在AVFrame.data[3]里面,是一个d3d9的Surface对象,里面装载着视频数据,数据格式通常为nv12。
下面是C#代码示例。

Play_VideoDisplay(IntPtr play, IntPtr[] data, int[] linesize, int width, int height, ACDll.ac_pixFormat format)
{//data为ffmpeg的AVFrame.datavar surface = Surface.FromPointer<Surface>(data[3]);
}

2.D3DImage

D3DImage是wpf提供与d3d互操作的对象。通常通过SetBackBuffer设置其背景缓存Surface,这个背景Surface就可以是d3d9的Surface对象,.AddDirtyRect更新前景Surface。与Image控件的source关联,显示到界面上。


二、如何实现?

1.创建RT Texture

需要渲染数据,必须先有一块缓存用来装载数据,因为dxva2解码出来的Surface对象数据格式通常是nv12不能直接使用,需要建立一个与设备格式兼容的缓存Texture,而且是RT类型,示例代码如下:

//data为ffmpeg的AVFrame.data,data[3]是d3d9 Surface对象
var surface = Surface.FromPointer<Surface>(data[3]);
//获取surface的device
var device = surface.Device;
//获取device的d3d对象
var d3d = device.Direct3D;
//通过device创建Texture
_texture = new Texture(device, width, height, 1, Usage.RenderTarget, d3d.GetAdapterDisplayMode(0).Format, Pool.Default);

2.设置D3DImage缓存

有了RT Texture,获取其内部的Surface作为D3DImage背景缓存。

//获取texture的surface
_textureSurface = _texture.GetSurfaceLevel(0);
//将texture的surface设置为D3DImage的背景缓存
_d3DImage = new D3DImage();
_d3DImage.Lock();
_d3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, _textureSurface.NativePointer);
_d3DImage.Unlock();

3.关联界面

因为D3DImage是ImageSource的子类,可以直接作为Image控件的Source。

//img_display为Image控件对象
img_display.Source=_d3DImage;

4.渲染

建立好联系后,通过StretchRectangle方法拷贝Surface数据,AddDirtyRect进行界面刷新。

//surface为dxva2解码数据,_textureSurface为D3DImage的背景缓存
device.StretchRectangle(surface, _textureSurface, TextureFilter.Linear);
d3DImage.Lock();
d3DImage.AddDirtyRect(new Int32Rect(0, 0, width, height));
d3DImage.Unlock();

三、示例代码

https://download.csdn.net/download/u013113678/85160884


四、效果预览

视频框内放置控件:

i7 核显渲染 hevc 4k 60fps性能:


五、性能对比

测试视频:hevc 4k 60fps
测试设备:i7 8750h gpu使用核显
数据记录:30秒内取5次值计算均值

渲染方式 cpu使用率(%) gpu使用率(%)
软解渲染 24.52 60.86
dxva2解码窗口句柄渲染 0.78 52.36
dxva2解码D3DImage渲染(本文) 1.22 56.04

看的出句柄渲染和D3DImage性能是比较接近的,相比之下软解渲染对性能的消耗就比较大了,所以D3DImage渲染dxva2是一个可用方案


总结

以上就是今天的内容了,曾以为dxva2解码渲染最佳性能方式只能通过窗口句柄渲染实现,但是经过尝试发现了通过D3DImage渲染也能够达到非常接近的性能,这样就很好的解决了在wpf中的绘制兼容问题,而且使用方式非常简单。


附录

1、C#操作d3d对象的库

通过nuget的方式获取,本文涉及到的库如下所示:

C# wpf 使用d3d渲染dxva2解码数据相关推荐

  1. C# wpf 使用d3d渲染yuv视频数据

    WPF视频渲染系列 第一章 使用HwndHost渲染视频 第二章 使用d3d渲染视频(本章) 第三章 使用d3d渲染dxva2数据 第四章 使用WriteableBitmap渲染视频 文章目录 WPF ...

  2. C# wpf 使用WriteableBitmap渲染视频

    WPF视频渲染系列 第一章 使用HwndHost渲染视频 第二章 使用d3d渲染视频 第三章 使用d3d渲染dxva2数据 第四章 使用WriteableBitmap渲染视频(本章) 文章目录 WPF ...

  3. C# wpf 通过HwndHost渲染视频

    WPF视频渲染系列 第一章 使用HwndHost渲染视频(本章) 第二章 使用d3d渲染视频 第三章 使用d3d渲染dxva2数据 第四章 使用WriteableBitmap渲染视频 文章目录 WPF ...

  4. 游戏修改器制作教程⑨:修改D3D渲染

    教程面向有C\C++基础的人,最好还要懂一些Windows编程知识 代码一律用Visual Studio 2013编译,如果你还在用VC6请趁早丢掉它... 写这个教程只是为了让玩家更好地体验所爱的单 ...

  5. 利用D3D抓取GPU数据

    microsoft 提供的D3D SDK是用来进行3D建模和利用GPU运算的一组接口的集合, D3D SDK至少有两个优点: 1.提供了一种3D建模的构架,程序员可以很容易的用这种构架来建模自己的3D ...

  6. 第一回 开篇 D3D渲染流程简介

    第一回 开篇 D3D渲染流程简介 http://developer.178.com/201004/65293187592.html 开发这个3D engine已经两年半了,从06年8月刚开始统计的4万 ...

  7. dotnet 读 WPF 源代码笔记 渲染收集是如何触发

    在 WPF 里面,渲染可以从架构上划分为两层.上层是 WPF 框架的 OnRender 之类的函数,作用是收集应用程序渲染的命令.上层将收集到的应用程序绘制渲染的命令传给下层,下层是 WPF 的 GF ...

  8. D3D渲染遇到的问题

    D3D渲染作为windows平台游戏及视频开发的一把利剑,做游戏是必须要用D3D这个渲染引擎,使用GUP来渲染,保证流畅度,GDI+真的不适合做大屏渲染和高帧率渲染,效率实在很差,毕竟是一款简单易用的 ...

  9. echarts数据变了不重新渲染,以及重新渲染了前后数据会重叠渲染的问题

    1.echarts数据变了但是视图不重新渲染 新建Chart.vue文件 <template>  <p :id="id" :style="style&q ...

最新文章

  1. elasticsearch 复杂查询小记
  2. 数据中心智能电源分配器(PDU)的趋势与应用
  3. 洛谷 - P1433 - 吃奶酪 - dfs
  4. 成为“能打”的二次元游戏《明日方舟》做对了什么?
  5. C#使用BackgroundWorker实现多线程
  6. 镭威视监控怎么复位_三大原因导致海康威视、大华股份近期连续暴跌
  7. 第5章 Python 数字图像处理(DIP) - 图像复原与重建10 - 空间滤波 - 统计排序滤波器 - 中值、最大值、最小值、中点、修正阿尔法均值滤波器
  8. leetcode 47. 全排列 II 思考分析
  9. Postman脚本发送请求pm.sendRequest
  10. 【POJ2559】Largest Rectangle in a Histogram(单调栈)
  11. 基于SSM的二手交易平台
  12. element ui 前台模板_简单了解Vue + ElementUI后台管理模板
  13. excel两列数据对比找不同_Excel两组数据做对比,用左右对比图才好看,操作简单又美观...
  14. FDA“长寿药”NMN被爆几毛一克,富豪被收天价智商税?
  15. ckplayer解析php源码,zblogphp视频主题使用ckplayer播放器说明
  16. [msyql]实战:关于回表的一次查询优化实战
  17. javascript库概念与连缀
  18. GNU/Linux与Windows魔兽争霸3局域网对战安装与配置
  19. 产品| 产品经理学习路径及职业规划
  20. Spring是什么,为什么要学Spring

热门文章

  1. 《程序员养成记》第7集 珍爱生命远离编程
  2. 洛谷试练场入门之“洛谷的第一个任务”讲解
  3. vi/vim 如何取消搜索高亮
  4. 西安自助游全攻略~~~~~很全的哦~~
  5. 虚拟内存的设置和相关问题的解决方法
  6. android usb连接不到手机,为什么手机USB连接不上电脑
  7. android 搭建FTP服务器
  8. 有序/无序分类变量的统计推断
  9. 22-05-10 西安 mysql基础篇(02) 修改表 、修改列、commit和rollback、表数据之增删改 DML 、列级约束、表级约束
  10. 和,II和I的区别与联系