如何使用 SharpDX 从 MediaFoundation 中的 MediaType 检索 VideoMediaType

How to retrieve VideoMediaType from a MediaType in MediaFoundation with SharpDX

我正在尝试使用 SharpDX.MediaFoundation (4.2.0) 从网络摄像头捕捉视频。我能够呈现默认媒体类型,但我希望能够 select 在设备的不同可用格式之间。

我可以枚举设备来源,但无法获取有关视频媒体类型的信息。

var attributes = new MediaAttributes(1);
attributes.Set(CaptureDeviceAttributeKeys.SourceType.Guid, CaptureDeviceAttributeKeys.SourceTypeVideoCapture.Guid);

var mediaSource = MediaFactory.EnumDeviceSources(attributes)[0].ActivateObject<MediaSource>();
mediaSource.CreatePresentationDescriptor(out var presentationDescriptor);

for (int d = 0; d < presentationDescriptor.StreamDescriptorCount; d++)
{
    presentationDescriptor.GetStreamDescriptorByIndex(d, out var isSelected, out var streamDescriptor);
    for (int i = 0; i < streamDescriptor.MediaTypeHandler.MediaTypeCount; i++)
    {
        var type = streamDescriptor.MediaTypeHandler.GetMediaTypeByIndex(i);
        if (type.MajorType == MediaTypeGuids.Video)
        {
            var v = type.QueryInterface<VideoMediaType>();
            // contains always empty values
            var x = v.VideoFormat;
        }
    }
}

QueryInterface 不工作。所以我尝试了

new VideoMediaType(type.NativePointer)

但结果是一样的。

此外,我对 SourceReader 进行了同样的尝试

 var reader = new SourceReader(mediaSource);
 var mediaTypeIndex = 0;

 using (var mt = reader.GetNativeMediaType(0, mediaTypeIndex))
 {
     if (mt.MajorType == MediaTypeGuids.Video)
     {
         //var vmt = new VideoMediaType(mt.NativePointer);
         var v = mt.QueryInterface<VideoMediaType>();
         var x = v.VideoFormat;
     }
 }

同样的结果。有什么建议吗?

您应该转换为 SharpDX MediaType,因为它对应于 IMFMediaType,但您已经在 mt 变量中拥有它了。 IMFMediaType 描述了来源提供的视频和音频媒体类型。 VideoMediaTypeIMFVideoMediaType 不保证可用。

您应该能够像这样使用它来访问 mt 中包含的视频媒体类型的不同属性:

using (var mt = reader.GetNativeMediaType(0, mediaTypeIndex))
{
    UnpackLong(mt.Get(MediaTypeAttributeKeys.FrameSize), out var width, out var height);
}

//Gets two integers from a long.
private void UnpackLong(long value, out int left, out int right)
{
    left = (int)(value >> 32);
    right = (int)(value & 0xffffffffL);
}

检查 SharpDX 接口 here(搜索 IMFMediaType)。