使用SharpDX.MediaFoundation获取DXVA解码器GUID异常求助
问题描述
作为DirectX新手,我在项目中使用SharpDX.MediaFoundation.DirectX库的VideoDecoderService类获取DXVA解码器GUID,目标是列出所有解码器并记录到日志文件。但遇到以下问题:
- 调用
GetDecoderDeviceGuids后,输出的count变量显示有42个解码器,但guids数组中仅第一个GUID的前8位有效,其余部分全为0,剩下的所有GUID都是全空值。 - 每次运行程序,第一个GUID的前8位会变化,其余始终为空。
示例输出:
- 0636e9a8-0000-0000-0000-000000000000
- 00000000-0000-0000-0000-000000000000
- ...
再次运行的输出:
- 068eebb8-0000-0000-0000-000000000000
- 00000000-0000-0000-0000-000000000000
- ...
完整代码示例
using System; using System.Windows; using SharpDX.Direct3D9; using SharpDX.MediaFoundation; using SharpDX.MediaFoundation.DirectX; namespace ListDecoders { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // Initialize Media Foundation MediaManager.Startup(); try { // Create a Direct3D device using (var d3dDevice = new Device(new Direct3D(), 0, SharpDX.Direct3D9.DeviceType.Hardware, IntPtr.Zero, CreateFlags.SoftwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, new PresentParameters { Windowed = true, BackBufferWidth = 640, BackBufferHeight = 480, BackBufferFormat = Format.Unknown, // or specify a format SwapEffect = SwapEffect.Discard, PresentFlags = PresentFlags.Video })) { // Create the VideoDecoderService with the Direct3D device using (var videoDecoderService = new VideoDecoderService(d3dDevice)) { // Get the DXVA decoder GUIDs var guids = GetDecoderDeviceGuids(videoDecoderService); // Output the GUIDs foreach (var guid in guids) { Console.WriteLine(guid); } } } } finally { // Shutdown Media Foundation MediaManager.Shutdown(); } } static Guid[] GetDecoderDeviceGuids(VideoDecoderService videoDecoderService) { var guids = new Guid[100]; // Adjust the array size as needed videoDecoderService.GetDecoderDeviceGuids(out int count, guids); // Trim the array to the actual count Array.Resize(ref guids, count); return guids; } } }
问题原因与解决方案
问题原因
- API调用方式错误:原生Media Foundation的
IMFVideoDecoderService::GetDecoderDeviceGuids要求分两次调用:第一次传入null获取解码器数量,第二次分配对应大小的数组填充GUID。当前代码直接分配固定数组并仅调用一次,导致内存封送错误,无法正确填充所有GUID。 - 设备类型不兼容:
VideoDecoderService需要Direct3D 11设备才能正确枚举DXVA硬件解码器,代码中使用的Direct3D 9设备不符合接口要求,进一步导致枚举异常。
修复步骤
1. 替换为Direct3D 11设备
使用Direct3D 11设备替代Direct3D 9设备,确保与Media Foundation的DXVA接口兼容。
2. 按规范调用GetDecoderDeviceGuids
分两次调用方法:先获取数量,再分配数组填充GUID。
修复后的代码
using System; using System.Windows; using SharpDX.Direct3D11; using SharpDX.MediaFoundation; using SharpDX.MediaFoundation.DirectX; namespace ListDecoders { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); MediaManager.Startup(); try { // 创建符合要求的Direct3D 11硬件设备 using (var device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport)) { using (var videoDecoderService = new VideoDecoderService(device)) { var guids = GetDecoderDeviceGuids(videoDecoderService); foreach (var guid in guids) { Console.WriteLine(guid.ToString("D")); } } } } finally { MediaManager.Shutdown(); } } static Guid[] GetDecoderDeviceGuids(VideoDecoderService videoDecoderService) { // 第一次调用:获取解码器总数 videoDecoderService.GetDecoderDeviceGuids(out int count, null); if (count == 0) return Array.Empty<Guid>(); // 第二次调用:分配对应大小的数组并填充GUID var guids = new Guid[count]; videoDecoderService.GetDecoderDeviceGuids(out _, guids); return guids; } } }
额外说明
- 确保项目引用
SharpDX.Direct3D11、SharpDX.MediaFoundation、SharpDX.DXGI三个库。 BgraSupport标志用于提升视频渲染兼容性,可根据场景选择是否保留。- 若问题仍存在,检查显卡驱动是否为最新版本,老旧驱动可能导致DXVA解码器枚举异常。
内容的提问来源于stack exchange,提问作者Lukáš Koten
相关产品推荐
相关产品推荐

