C# wpf 使用d3d渲染yuv视频数据
文章目录前言一、如何实现1.继承D3DImage2.关联D3D93.写入数据二、完整代码三、使用方法三、效果预览总结前言在《C# wpf 通过HwndHost渲染视频》中介绍了一种在wpf渲染视频的方法,但是有一个缺点,和wpf的控件不太契合,无法在播放框放控件,也无法改变形状,导致一些界面需求较难实现。为了解决这一问题,找到了一种可以和wpf绘制兼容的视频渲染方式,使用d3d渲染。一、如何实现我
WPF视频渲染系列
第一章 使用HwndHost渲染视频
第二章 使用d3d渲染视频(本章)
第三章 使用d3d渲染dxva2数据
第四章 使用WriteableBitmap渲染视频
前言
在《C# wpf 通过HwndHost渲染视频》中介绍了一种在wpf渲染视频的方法,但是有一个缺点,和wpf的控件不太契合,无法在播放框放控件,也无法改变形状,导致一些界面需求较难实现。为了解决这一问题,找到了一种可以和wpf绘制兼容的视频渲染方式,使用d3d渲染。
一、如何实现?
我们首先选择用Image
控件来显示视频,Image控件有个Source属性,类型是ImageSource。
1.继承D3DImage
在System.Windows.Interop中有个D3DImage即是ImageSource的子类。
.net源码如下:
namespace System.Windows.Interop
{
//
// 摘要:
// An System.Windows.Media.ImageSource that displays a user-created Direct3D surface.
public class D3DImage : ImageSource
}
我们需要继承这个类,自定义一个D3DImageSource继承D3DImage:
public class D3DImageSource : D3DImage
{
/// <summary>
/// 渲染
/// </summary>
/// <param name="data">数据,比如YU12放在data[0-2]、NV12放在data[0-1]、ARGB32放在data[0]</param>
/// <param name="lineSize">linesize表示每行数据长度。d3d渲染是64位对齐的。由外部确保内存对齐,方法内部重新处理内存对齐效率是不高的,最好的方式是外部构造数据时已经内存对齐。</param>
public void Present(IntPtr[] data, int[] lineSize);
/// <summary>
/// 清除画面
/// </summary>
public void Clear();
}
2.关联D3D9
(1)安装SharpDx
D3DImage可以使用D3D对象写数据,在.net中有个Dx的封装叫SharpDx可以使用D3D,安装方可以在vs2019中可以通过类名直接自动安装。
(2)设置缓冲区
初始化D3D9对象后,设置D3DImage的缓冲区为D3D9的Surface:
D3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, textureSurface.NativePointer);
3.写入数据
往Surface写入数据
DataRectangle rect = surface.LockRectangle(LockFlags.None);
IntPtr surfaceBufferPtr = rect.DataPointer;
//内存拷贝写入YUV数据
surface.UnlockRectangle();
二、完整代码
https://download.csdn.net/download/u013113678/40831794
三、使用方法
将Image控件的Source设置为D3DImageSource对象,视频数据写入D3DImageSource对象即可。
(1)定义Image控件
<Image x:Name="Img_Diplay" Height="360" Width="640" >
(2)关联D3DImageSource
D3DImageSource d3dImageSource = new D3DImageSource(width, height, FrameFormat.YV12);
Img_Diplay.Source = d3dImageSource;
(3)写入数据
其中data和linesize可以参考ffmpeg
d3dImageSource.Present(data, linesize);
(4)释放资源
使用完成后需要释放资源
d3dImageSource.Dispose();
四、效果预览
视频框内放置控件:
圆角视频框:
通过绑定实现多个视频框显示同一个画面:
总结
通过Image关联到D3DImage,再通过D3DImage关联到D3D9,实现了通过D3D9渲染画面到Image的功能,这种方法的渲染机制与wpf一致,所以可以兼容wpf控件,有了很好的兼容性就意味着可以使用wpf的各种强大界面功能,极大的降低了开发难度以及提升了界面的可造性。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)