我正在尝试使用Direct2D和WIC Bitmap制作一个简单的视频播放器 它需要YUV像素格式帧数据的快速和CPU经济绘制(有拉伸)。
我已经用GDI测试了。我希望切换到Direct2D可以获得至少10倍的性能提升(较小的CPU开销)。
我要做的基本上如下:
对于1,2步,我必须选择像素格式 WIC Native Pixel Formats
MSDN网页建议使用WICPixelFormat32bppPBGRA
http://msdn.microsoft.com/en-us/library/windows/desktop/hh780393(v=vs.85).aspx
有什么区别WICPixelFormat32bppPBGRA
和WICPixelFormat32bppBGRA
? (前者有额外的P)
如果WICPixelFormat32bppPBGRA
是可行的方式,情况总是如此吗?无论硬件和/或配置如何?
实际上WIC位图处理最有效的像素格式是什么?
答案 0 :(得分:5)
不幸的是,使用Direct2D 1.1或更低版本,你不能使用与 DXGI_FORMAT_B8G8R8A8_UNORM 不同的pixelformat,这相当于WIC的 WICPixelFormat32bppPBGRA (如果你使用 D2D1_ALPHA_MODE_PREMULTIPLIED,则为“P” D2D中的alpha模式。)
如果您在Windows 8中使用目标操作系统,则可以使用Direct2D的新功能。据我记得,对D2D位图有一些YUV支持。 (编辑:不,没有.RGB32仍然是唯一支持的像素格式以及一些仅alpha格式)
实际上WIC位图处理最有效的像素格式是什么?
我不确定如何测量像素格式的有效性,但如果要使用硬件加速,则应使用D2D而不是WIC进行绘制,并仅将WIC用于颜色空间转换。 (GDI也是硬件加速btw)。
WICPixelFormat32bppPBGRA和WICPixelFormat32bppBGRA有什么区别? (前者有 额外的P)
P表示RGB组件是预乘的。 (see here)
我要做的基本上如下:
- 创建一个空的WIC位图A(用于绘制画布)
- 使用YUV帧数据(格式转换)创建另一个WIC位图B
- 将位图B绘制到A上,然后将A绘制到D2D渲染目标
醇>
如果你的目标是性能,你应该最小化位图复制操作,你应该避免使用WIC位图渲染目标,因为它使用软件渲染。如果您的播放器只渲染到一个窗口,您可以使用HWND render target或DeviceContext使用交换链(取决于您使用的Direct2D版本)。
您可以使用WIC的软件像素格式转换功能(例如IWICFormatConverter),而不是将帧 B 渲染为 A 。另一种方法是使用SIMD操作编写(或查找)自定义转换例程。或使用着色器转换 GPU端上的格式(颜色空间)。但后两者需要先进的知识。
转换后,您可以锁定像素以获取像素数据,并直接将数据复制到D2D位图(ID2D1Bitmap::CopyFromMemory())。鉴于您已经有一个准备好的d2d位图。
最后一步是将位图渲染到渲染目标。并且您可以使用转换矩阵来实现拉伸。