通过 DirectShow 枚举可用的相机分辨率
Enumerating Available Camera Resolutions via DirectShow
我正在尝试使用通过 COM 从 WPF 访问的 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 Capture Capabilities 工具并获得了以下可疑功能:
能力: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
.subtype
: FourCC YUY2
.bFixedSizeSamples
: 1
.bTemporalCompression
: 0
.lSampleSize
: 614,400
.cbFormat
: 112
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);
}
上述更改似乎有效,例如它正在我的测试相机上工作。这看起来正确吗?这段代码还有什么我应该担心的吗???
I believe that mediaType is picking up some audio capabilities as well as video. [...]
How would I enumerate only the video capabilities and eliminate audio?
尽管可能,视频和音频功能以及媒体类型在特定引脚上混合的可能性很小。也就是说,正确枚举它,您将只得到视频的,或者只得到音频的,具体取决于引脚。
您始终可以将枚举与 GraphEdit 显示的媒体类型进行比较,GraphStudioNext or DirectShowCaptureCapabilities。
我正在尝试使用通过 COM 从 WPF 访问的 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 Capture Capabilities 工具并获得了以下可疑功能:
能力:1AM_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
.subtype
:FourCC YUY2
.bFixedSizeSamples
:1
.bTemporalCompression
:0
.lSampleSize
:614,400
.cbFormat
:112
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);
}
上述更改似乎有效,例如它正在我的测试相机上工作。这看起来正确吗?这段代码还有什么我应该担心的吗???
I believe that mediaType is picking up some audio capabilities as well as video. [...]
How would I enumerate only the video capabilities and eliminate audio?
尽管可能,视频和音频功能以及媒体类型在特定引脚上混合的可能性很小。也就是说,正确枚举它,您将只得到视频的,或者只得到音频的,具体取决于引脚。
您始终可以将枚举与 GraphEdit 显示的媒体类型进行比较,GraphStudioNext or DirectShowCaptureCapabilities。