【DirectX3D - 5】渲染多路视频(单一窗口)

概述

windows 平台下视频渲染技术

  1. GDI
    图形设备接口(Graphics Device Interface)。主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形和图像输出。GDI的出现使程序员无需要关心硬件设备及设备正常驱动,就可以将应用程序的输出转化为硬件设备上的输出和构成,实现了程序开发者与硬件设备的隔离,大大方便了开发工作。
    关于GDI的简介可以阅读这篇文章

  2. DirectDraw
    DirectDraw是微软发行的DirectX SDK中的一部分。DirectDraw已经过时,取而代之的是Direct2D。
    Direct2D 是一种硬件加速的即时模式二维图形 API,可为二维几何对象、位图和文本提供高性能、高质量的呈现。Direct2D API 可与使用 GDI、GDI+ 或 Direct3D 的现有代码进行交互。

  3. Direct3D
    Direct3D就是本文使用的渲染方式。我们在前文渲染图片也讲过了,主要有两种渲染方法,一种是使用Surface,另一种是使用Texture。

  4. OpenGL
    Open Graphics Library,开放图形库。
    用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。这个接口由近350个不同的函数调用组成,用来绘制从简单的图形比特到复杂的三维景象。

说明
Direct3D 接口适用于 Windows平台
OpenGL 是跨平台的。

本文目的

基于D3D技术,使用其中的纹理方法,实现仅创建一个窗口,渲染多路视频。
一般的,在视频监控领域,显示多个视频,每一个视频都是一个独立的窗口。为了减少窗口的资源和管理,本文中介绍的方法是仅创建一个窗口,使用纹理内存的顶点映射方法,在一个大窗口中显示不同路的视频。

实现步骤

基本步骤

  1. 创建大窗口
  2. 创建统一的D3D设备资源
  3. 将大窗口划分为多个子区域,每一个子区域就是之后纹理内存映射的位置
  4. 为纹理内存填充视频数据
  5. 统一刷新

两种方式

实现方式分为两种,单独使用CPU渲染,单独使用GPU渲染。
两种方式基本步骤一致。

  • CPU渲染,是因为解码数据也是CPU实现的,视频数据来源于CPU,然后直接使用CPU渲染。
  • GPU渲染,是因为解码数据基于GPU实现,视频数据来源于GPU显存,不需要将显存数据做DtoH的拷贝操作,直接使用GPU资源渲染,减少资源拷贝的实践消耗。
  • 两者的区别仅在于视频数据的来源,以及是否需要注册纹理资源。

窗口说明

在这里插入图片描述
举例说明:
上述1920x1080的窗口,要显示16个小区域,纹理顶点映射要做的就是,将1920x1080的视频分别映射到上述的每一个小区域中。
这其实是一个大窗口,针对这一个大窗口,创建一个D3D设备,对于所有的画面,执行统一的刷新(Present)。

代码说明

本节将介绍关键代码的使用和注意。

// 数据结构
// 全局句柄
IDirect3D9* pD3D;
IDirect3DDevice9* pDevice;
// 刷新线程
pthread *pRenderThread;

// 1. 创建设备
//  CPU渲染方式
pD3D = Direct3DCreate9(D3D_SDK_VERSION);
ret = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL,
	D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &(pDevice));

//  GPU 渲染方式
Direct3DCreate9Ex(D3D_SDK_VERSION, &(pDev->pD3DEx));
ret = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL,
	D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &(pDevice));
/*
	区别:GPU渲染必须 使用 HARDWARE 顶点映射格式:D3DCREATE_HARDWARE_VERTEXPROCESSING
*/


// 2. 创建纹理,CPU和 GPU设置的格式不同,如下代码
DWORD usage;
D3DFORMAT format;
D3DPOOL pool;

if (E_CPU == iRendertype) {
	usage = D3DUSAGE_SOFTWAREPROCESSING;
	pool = D3DPOOL_MANAGED;
	format = D3DFMT_A8R8G8B8;
}
else if (E_GPU == iRendertype) {
	DWORD usage = D3DUSAGE_RENDERTARGET;
	D3DFORMAT format = D3DFMT_X8R8G8B8;
	D3DPOOL pool = D3DPOOL_DEFAULT;
}
ret = pDevice->CreateTexture(width, height, 1, usage, format, pool, &(pTexture), NULL);

// GPU需要纹理注册到GPU对应的显存
/*
	pTexture:上一步骤申请的纹理空间
	
	cuResource:CUgraphicsResource cuResource;		
	// cuda对应的d3d11纹理映射,pTexture要注册到cuResource
*/
D3DLOCKED_RECT lr;
pTexture->LockRect(0, &lr, NULL, 0);
{
	// 省略了GPU上下文
	CUresult ret = cuGraphicsD3D9RegisterResource(&cuResource, pTexture, CU_GRAPHICS_REGISTER_FLAGS_NONE);
	ck(cuGraphicsResourceSetMapFlags(cuResource,CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD));
}
pTexture->UnlockRect(0);

以上步骤基本就是渲染视频的关键步骤。

附录

渲染技术过去的历史
视频渲染方法简介:

1、.视频覆盖:
  大概在1995年,当mpeg1(VCD)回放在PC上开始流行的时候,PC的处理能力还么有强大到实时播放的地步。显卡制造厂商适时的推出了"video overlay(视频覆盖)"的技术。它就是种在显卡上用硬件完成同时显示几个视频的功能(拉伸,颜色空间变换,等等…)的技术,这样就可以在PC上流畅的播放动画而不占用cpu。视频覆盖的画面质量事实上取决于显卡硬件。我发现市面上的绝大部分的显卡显示视频覆盖质量都很不行。在视频覆盖上用视频渲染技术的一个最大的关键就是在每个显卡上只有一个视频覆盖 unit(单元). 这样就迫切的需要多显示器系统了。

2、Direct3D:
  Direct3D是微软提供给程序员使用一个不断进化的功能集合的DirectX库的一部分。在direct9 中,微软给出了一套新的功能,性能接近于覆盖 surface(接口),但是没那么多限制。视频渲染技术基于direct3d比视频覆盖提供了更好的图像质量,还没有视频覆盖单显示器的麻烦。但是,不是所有的显卡都支持这个技术,还有一些根本不支持,很多不支持整套功能集。

3、系统默认渲染器:
  当播放器用默认回放模式播放媒体文件的时候,在低于windows xp的所有windows系统上或者windowsxp的"vmr7", 用系统默认渲染器就意味着"标准覆盖" 。

4、标准覆盖渲染器:
  这是最老的视频渲染技术了。在可用的时候它用到视频覆盖,当视频不可用的时候就退回到纯cpu控制视频。纯cpu控制就是说cpu替代了视频覆盖来干这些事情。这对回放是个沉重的打击(cpu更辛苦了),这个渲染的缺点是它不支持固定屏幕高宽比控制,硬件颜色控制(色调/饱和度/亮度/对比度/gamma(灰度))不可操作,而且抓图结果会很很奇怪。

5、覆盖混合渲染:
  同样是运用视频覆盖技术,这个渲染器允许在那些支持颜色控制的硬件上进行颜色控制(色调/饱和度/亮度/对比度/gamma)。有些卡可能只支持颜色控制的一个子集(比如只有亮度)。这个渲染器也支持固定宽高比控制,只要媒体文件支持这个渲染器,缺点就是它返回到纯cpu控制。当视频覆盖不可操作时,它就罢工了。在媒体模式的这个情况时候,就会回到标准覆盖渲染。在dvd模式时,会报错说视频解码器不能连接到覆盖混合器。最后,这个渲染技术还是抓图的效果不够好。

6、视频混合渲染器7(vmr7):
  这个渲染器是视频覆盖技术和direct3d技术的结合,它只在windows xp上有效,后来被vmr9取代了。windows media player 7-10使用这个技术.这个渲染技术默认使用视频覆盖。然而,如果它不可用了,它可以有限的使用direct3d。它的缺点是不可进行颜色控制,截屏还是不够好。

7、视频混合渲染器9(vmr9):
  这是最新的视频渲染技术。它完全建筑在direct3d上,需要direct9和最新的硬件。它可以提供最好的画质(取决于渲染模式和显卡)。vmr9支持硬件颜色操作(如果卡支持),但是没有gamma控制,因为ms没有提供。 vmr9也有宽高比控制。

8、EVR增强渲染模式(vista系统):
  Vista新引入了全新的EVR渲染器,微软的技术文档倒是把这个东东吹得很强劲,但是就目前来说问题还是不少。第一个就是字幕的问题,目前用EVR是无法在高速或者急速模式下把字幕显示出来。那个EVR C/A 倒是能够显示字幕,不过dxva2.0就会失效,换句话说就无法开启geforce8显卡的硬件解码功能。还有一个问题就是色阶或者黑位问题,这个问题在VMR9下可以通过shader得到完美的解决方案,现在到了EVR,色阶问题目前可以说几乎毫无办法,最多能用一下coreavc的fix color功能解决一下,但是还是有相当大的局限性。

另:VMR9支持3种特别的渲染模式:
A.vmr9:窗口:
  这种是最基本的模式,它向后兼容,但不支持帧抓屏,要提醒一点,这个模式在windows sp1和directx9b下有bug,在dvd菜单导航时只能用这个模式了。在windowsxp sp2和direct9c下这个bug没了。
B.wmr9:窗口无转换:
  这个模式比窗口模式高级点,用来截图是最好的。
C.wmr9:渲染无转换:
  这个可是vmr9中最复杂的渲染模式,它可以工作在direct3d独占模式,那就是整个机器被设定为全屏,其他运行的程序不可以操作视频硬件,在这个独占模式下,所耗cpu更少,分辨率越高,回放就更平滑。缺点是在独占模式下,整个机器都献身给视频回放了,你不能干其他任何事情了。

参考资料

[1] http://blog.sina.com.cn/s/blog_53902eeb010091qj.html
[2] https://blog.csdn.net/CrystalShaw/article/details/91388983
[3] 《CUDA Driver API》402页

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值