通过DirectShow枚举可用的相机分辨率

时间:2017-08-18 11:58:37

标签: wpf directshow

我正在尝试使用从WPF通过COM访问的DirectShow来枚举USB摄像头的视频分辨率。 我有以下测试代码。

var videoOutPin = this.BaseFilterObject.GetPin(PinDirection.Output, 0);

var streamConfig = (IAMStreamConfig)videoOutPin;

var piCount = 0;
var piSize = 0;

if (streamConfig.GetNumberOfCapabilities(ref piCount, ref piSize) != 0)
{
    return;
}

this.mediaTypes = new Collection<AMMediaType>();

var resolutions = new Collection<string>();

var ptr = Marshal.AllocCoTaskMem(piSize);

for (var i = 0; i < piCount; i++)
{
    var mediaType = new AMMediaType();
    if (streamConfig.GetStreamCaps(i, ref mediaType, ptr) != 0)
    {
        continue;
    }

    var header = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader));

    var resolution = header.BmiHeader.BitCount + " bits : " + header.BmiHeader.Width + " * " + header.BmiHeader.Height;

    this.mediaTypes.Add(mediaType);
    resolutions.Add(resolution);
}

但是,我相信mediaType正在提供一些音频功能以及视频。例如。每隔一次迭代都会给我一个header.BmiHeader.Width为0,header.BmiHeader.BitCount为0。

首先,我认为这是因为使用VideoInfoHeader投射音频功能所致。

我如何仅枚举视频功能并消除音频?

==============================

修改

我使用了DirectShow捕获功能工具并获得了以下可疑功能:

能力:1
  • AM_MEDIA_TYPE
    • 数据:76 69 64 73 00 00 10 00 80 00 00 AA 00 38 9B 71 59 55 59 32 00 00 10 00 80 00 00 AA 00 38 9B 71 01 00 00 00 00 00 00 00 00 60 09 00 A0 76 2A F7 0A EB D0 11 AC E4 00 00 C0 CC 16 BA 00 00 00 00 70 00 00 00 40 07 B3 03
    • 格式数据:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CA 08 00 00 00 00 15 16 05 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 03 00 00 00 81 26 8D 00 00 00 00 00 28 00 00 00 80 02 00 00 E0 01 00 00 01 00 10 00 59 55 59 32 00 60 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    • .subtypeFourCC YUY2
    • .bFixedSizeSamples1
    • .bTemporalCompression0
    • .lSampleSize614,400
    • .cbFormat112
    • VIDEOINFOHEADER2
  • 未知功能:
    • 输入:{F72A76A0-EB0A-11D0-ACE4-0000C0CC16BA}
    • 数据:A0 76 2A F7 0A EB D0 11 AC E4 00 00 C0 CC 16 BA 00 00 00 00 80 02 00 00 E0 01 00 00 80 02 00 00 E0 01 00 00 80 02 00 00 E0 01 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 80 02 00 00 E0 01 00 00 80 02 00 00 E0 01 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 16 05 00 00 00 00 00 15 16 05 00 00 00 00 00 00 00 CA 08 00 00 CA 08

这是否有意义?

==============================

编辑#2

遵循Roman R.的建议(如果我理解正确的话)。

我宣布: -

private static readonly Guid VideoInfo =
        new Guid(0x05589F80, 0xC356, 0x11CE, 0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A);

然后按如下方式修改代码:

 for (var i = 0; i < piCount; i++)
        {
            var mediaType = new AMMediaType();
            if (streamConfig.GetStreamCaps(i, ref mediaType, ptr) != 0)
            {
                continue;
            }

           if (mediaType.FormatType != VideoInfo)
            {
                continue;
            }

            Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader));

            var header = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader));

            var resolution = header.BmiHeader.BitCount + " bits : " + header.BmiHeader.Width + " * "
                             + header.BmiHeader.Height;

            this.mediaTypes.Add(mediaType);
            resolutions.Add(resolution);
        }

上述变化似乎有效,例如它正在我的测试相机上工作。这看起来是否正确。还有什么我应该担心这个代码???

1 个答案:

答案 0 :(得分:0)

  

我相信mediaType正在提供一些音频功能以及视频。 [...]

     

我如何仅枚举视频功能并消除音频?

即使可能,视频和音频功能以及媒体类型也不太可能在特定引脚上混合。也就是说,列举它是正确的,你只得到视频,或根据引脚只是音频。

您始终可以将枚举与GraphEdit,GraphStudioNextDirectShowCaptureCapabilities所显示的媒体类型进行比较。