我正在尝试使用Direct2D和WIC位图来制作简单的video播放器。
它需要YUV像素格式帧数据的快速和CPU经济绘图(带有拉伸)。
我已经用GDI进行了testing。 我希望切换到Direct2D至less提供10倍的性能增益(较小的CPU开销)。
我会做的基本上如下所示:
对于1,2步,我必须select一个像素格式。
WIC本机像素格式
有一个MSDN页面build议WICPixelFormat32bppPBGRA
。
http://msdn.microsoft.com/en-us/library/windows/desktop/hh780393(v=vs.85).aspx
有什么区别WICPixelFormat32bppPBGRA
和WICPixelFormat32bppBGRA
? (前者有附加P)
如果WICPixelFormat32bppPBGRA
是要走的路,情况总是如此吗? 无论硬件和/或configuration?
实际上WIC位图处理最有效的像素格式是什么?
不幸的是,使用Direct2D 1.1或更低版本,不能使用不同于DXGI_FORMAT_B8G8R8A8_UNORM的像素格式,该格式等同于WIC的WICPixelFormat32bppPBGRA (如果在D2D中使用D2D1_ALPHA_MODE_PREMULTIPLIED alpha模式, 则为 “P”)。
如果你在Windows 8的目标操作系统,那么你可以使用Direct2D的新功能。 据我所知,D2D位图有一些YUV支持。 ( 编辑:不,没有,RGB32仍然是唯一的像素格式支持以及一些只有阿尔法的格式)
实际上WIC位图处理最有效的像素格式是什么?
我不确定如何测量像素格式的有效性,但是如果您要使用硬件加速,则应该使用D2D而不是WIC来绘制,并且仅将WIC用于颜色空间转换。 (GDI也是硬件加速btw)。
有什么区别WICPixelFormat32bppPBGRA和WICPixelFormat32bppBGRA? (前者有附加P)
P表示RGB组件是预乘。 ( 见这里 )
我会做的基本上如下所示:
- 创建一个空的WIC位图A(用于绘制画布)
- 用YUV帧数据(格式转换)创建另一个WIC位图B
- 将位图B绘制到A上,然后将A绘制到D2D渲染目标上
如果你的目标是性能,你应该尽量减少位图复制操作,也应该避免使用WIC位图渲染目标 ,因为它使用的是软件渲染 。 如果你的播放器只渲染一个窗口,你可以使用HWND渲染目标 ,或者使用Swap Chain的DeviceContext (取决于你使用的Direct2D版本)。
您可以使用WIC的软件像素格式转换特性(例如IWICFormatConverter ),而不是将帧B渲染到帧A. 另一种方法是使用SIMD操作编写(或查找)自定义转换例程。 或者使用着色器来转换GPU端的格式(色彩空间)。 但后两者需要先进的知识。
转换后,您可以锁定像素以获取像素数据,并将该数据直接复制到D2D位图( ID2D1Bitmap :: CopyFromMemory() )。 鉴于你已经有了一个准备好的d2d位图。
最后一步是将位图渲染到渲染目标。 你可以使用变换矩阵来实现拉伸。