配置视频输出格式
[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayer、 IMFMediaEngine 和 音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
注意
本主题中所述的功能已弃用。 若要配置捕获设备的输出格式,应用程序应在 pmt 参数中使用 IAMStreamConfig::GetFormat 返回的AM_MEDIA_TYPE结构。
捕获设备可以支持一系列输出格式。 例如,设备可能支持 16 位 RGB、32 位 RGB 和 YUYV。 在上述每种格式中,设备可以支持一系列帧大小。
在 WDM 设备中, IAMStreamConfig 接口用于报告设备支持的格式并设置格式。 (对于旧版 VFW 设备,请使用“视频格式 VFW”对话框,如 显示 VFW 捕获对话框中所述。) IAMStreamConfig 接口在捕获筛选器的捕获引脚和/或预览引脚上公开。 使用 ICaptureGraphBuilder2::FindInterface 方法获取接口指针:
IAMStreamConfig *pConfig = NULL;
hr = pBuild->FindInterface(
&PIN_CATEGORY_PREVIEW, // Preview pin.
0, // Any media type.
pCap, // Pointer to the capture filter.
IID_IAMStreamConfig, (void**)&pConfig);
设备具有它支持的媒体类型的列表。 对于每种媒体类型,设备还提供一组功能。 其中包括可用于该格式的帧大小范围、设备拉伸或收缩图像的大小以及帧速率范围。
若要获取媒体类型的数量,请调用 IAMStreamConfig::GetNumberOfCapabilities 方法。 方法返回两个值:
- 媒体类型的数量。
- 保存功能信息的结构的大小。
大小值是必需的,因为 IAMStreamConfig 接口用于音频和视频 (,并且可以扩展到其他媒体类型) 。 对于视频,这些功能是使用 VIDEO_STREAM_CONFIG_CAPS 结构描述的,而音频使用 AUDIO_STREAM_CONFIG_CAPS 结构。
若要枚举媒体类型,请使用从零开始的索引调用 IAMStreamConfig::GetStreamCaps 方法。 GetStreamCaps 方法返回媒体类型和相应的功能结构:
int iCount = 0, iSize = 0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
// Check the size to make sure we pass in the correct structure.
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
{
// Use the video capabilities structure.
for (int iFormat = 0; iFormat < iCount; iFormat++)
{
VIDEO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE *pmtConfig;
hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
if (SUCCEEDED(hr))
{
/* Examine the format, and possibly use it. */
// Delete the media type when you are done.
DeleteMediaType(pmtConfig);
}
}
请注意如何为 GetStreamCaps 方法分配结构。 方法分配媒体类型结构,而调用方分配功能结构。 将功能结构强制转换为字节数组指针。 使用完媒体类型后,删除 AM_MEDIA_TYPE 结构以及媒体类型的格式块。
可以将设备配置为使用 GetStreamCaps 方法中返回的格式。 只需使用媒体类型调用 IAMStreamConfig::SetFormat :
hr = pConfig->SetFormat(pmtConfig);
如果引脚未连接,则会尝试在连接时使用此格式。 如果引脚已连接,它将尝试使用新格式重新连接。 在任一情况下,下游筛选器都可能会拒绝格式。
还可以在将媒体类型传递给 SetFormat 方法之前对其进行修改。 这是 VIDEO_STREAM_CONFIG_CAPS 结构的来源。 它介绍了更改媒体类型的所有有效方法。 若要使用此信息,必须了解该特定媒体类型的详细信息。
例如,假设 GetStreamCaps 返回 24 位 RGB 格式,其帧大小为 320 x 240 像素。 可以通过检查媒体类型的主要类型、子类型和格式块来获取此信息:
if ((pmtConfig.majortype == MEDIATYPE_Video) &&
(pmtConfig.subtype == MEDIASUBTYPE_RGB24) &&
(pmtConfig.formattype == FORMAT_VideoInfo) &&
(pmtConfig.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
(pmtConfig.pbFormat != NULL))
{
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig.pbFormat;
// pVih contains the detailed format information.
LONG lWidth = pVih->bmiHeader.biWidth;
LONG lHeight = pVih->bmiHeader.biHeight;
}
VIDEO_STREAM_CONFIG_CAPS结构提供可用于此媒体类型的最小和最大宽度和高度。 它还提供“步长”大小,用于定义调整宽度或高度的增量。 例如,设备可能会返回以下内容:
- MinOutputSize:160 x 120
- MaxOutputSize:320 x 240
- OutputGranularityX:8 像素 (水平步长)
- OutputGranularityY:8 像素 (垂直步长)
给定这些数字,可以将宽度设置为 (160、168、176...304、312、320) 和高度 (在 120、128、136...104、112、120) 。 下图演示了此过程。
若要设置新的帧大小,请直接修改 GetStreamCaps 中返回的AM_MEDIA_TYPE结构:
pVih->bmiHeader.biWidth = 160;
pVih->bmiHeader.biHeight = 120;
pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);
然后,将媒体类型传递给 SetFormat 方法,如前所述。
VIDEO_STREAM_CONFIG_CAPS的 MinFrameInterval 和 MaxFrameInterval 成员是每个视频帧的最小和最大长度,可将其转换为帧速率,如下所示:
frames per second = 10,000,000 / frame duration
若要请求特定的帧速率,请修改媒体类型中 VIDEOINFOHEADER 或 VIDEOINFOHEADER2 结构中的 AvgTimePerFrame 的值。 设备可能不支持最小值和最大值之间的每个可能值,因此驱动程序将使用最接近的值。 若要查看驱动程序实际使用的值,请在调用 SetFormat 后调用 IAMStreamConfig::GetFormat。
某些驱动程序可能会报告 MaxFrameInterval 值的 MAXLONGLONG (0x7FFFFFFFFFFFFFFF) ,这实际上意味着没有最长持续时间。 但是,你可能希望在应用程序中强制实施最小帧速率,例如 1 fps。
相关主题