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

WPF视频渲染系列

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


文章目录

  • WPF视频渲染系列
  • 前言
  • 一、如何实现?
    • 1.继承D3DImage
    • 2.关联D3D9
    • 3.写入数据
  • 二、完整代码
  • 三、使用方法
  • 四、效果预览
  • 总结


前言

在《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
{
        /// 
        /// 渲染
        /// 
        /// 数据,比如YU12放在data[0-2]、NV12放在data[0-1]、ARGB32放在data[0]
        /// linesize表示每行数据长度。d3d渲染是64位对齐的。由外部确保内存对齐,方法内部重新处理内存对齐效率是不高的,最好的方式是外部构造数据时已经内存对齐。
        public void Present(IntPtr[] data, int[] lineSize);
         /// 
        /// 清除画面
        /// 
        public void Clear();      
}

2.关联D3D9

(1)安装SharpDx
D3DImage可以使用D3D对象写数据,在.net中有个Dx的封装叫SharpDx可以使用D3D,安装方可以在vs2019中可以通过类名直接自动安装。
C# wpf 使用d3d渲染yuv视频数据_第1张图片
(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();

四、效果预览

视频框内放置控件:
C# wpf 使用d3d渲染yuv视频数据_第2张图片
圆角视频框:
C# wpf 使用d3d渲染yuv视频数据_第3张图片
通过绑定实现多个视频框显示同一个画面:
C# wpf 使用d3d渲染yuv视频数据_第4张图片


总结

通过Image关联到D3DImage,再通过D3DImage关联到D3D9,实现了通过D3D9渲染画面到Image的功能,这种方法的渲染机制与wpf一致,所以可以兼容wpf控件,有了很好的兼容性就意味着可以使用wpf的各种强大界面功能,极大的降低了开发难度以及提升了界面的可造性。

你可能感兴趣的:(#,wpf,音视频,音视频,c#,wpf)