You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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;
        }
    }
}
问题原因与解决方案

问题原因

  1. API调用方式错误:原生Media Foundation的IMFVideoDecoderService::GetDecoderDeviceGuids要求分两次调用:第一次传入null获取解码器数量,第二次分配对应大小的数组填充GUID。当前代码直接分配固定数组并仅调用一次,导致内存封送错误,无法正确填充所有GUID。
  2. 设备类型不兼容: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:57:14