设置去交错首选项
[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayer、 IMFMediaEngine 和 媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
(VMR) 的视频混合呈现器支持硬件加速的去交错,从而提高交错视频的呈现质量。 可用的确切功能取决于基础硬件。 应用程序可以通过 IVMRDeinterlaceControl 接口 (VMR-7) 或 IVMRDeinterlaceControl9 接口 (VMR-9) 来查询硬件去隔行功能并设置去交错首选项。 按流执行去交错。
VMR-7 和 VMR-9 之间的交错行为有一个重要区别。 在图形硬件不支持高级去交错的系统上,VMR-7 可以回退到硬件覆盖层,并指示它使用 BOB 样式的去交错。 在这种情况下,尽管 VMR 报告了 30fps,但视频实际上以每秒 60 次翻转的速度呈现。
除使用硬件覆盖的 VMR-7 的情况外,由 VMR 的混音器执行去交错。 混音器使用 DirectX 视频加速 (DXVA) 去交错设备驱动程序接口 (DDI) 来执行去交错。 应用程序不可调用此 DDI,并且应用程序无法替换 VMR 的反交错功能。 但是,应用程序可以选择所需的去交错模式,如本部分所述。
注意
本部分介绍 IVMRDeinterlaceControl9 方法,但 VMR-7 版本几乎相同。
若要获取视频流的去隔行功能,请执行以下操作:
- 使用视频流的说明填充 VMR9VideoDesc 结构。 稍后会提供有关如何填充此结构的详细信息。
- 将 结构传递给 IVMRDeinterlaceControl9::GetNumberOfDeinterlaceModes 方法。 调用方法两次。 第一个调用返回硬件支持的指定格式的反交错模式数。 分配此大小的 GUID 数组,然后再次调用 方法,传入数组的地址。 第二次调用使用 GUID 填充数组。 每个 GUID 标识一个去交错模式。
- 若要获取特定模式的值,请调用 IVMRDeinterlaceControl9::GetDeinterlaceModeCaps 方法。 传入相同的 VMR9VideoDesc 结构,以及数组中的一个 GUID。 方法使用 模式功能填充 VMR9DeinterlaceCaps 结构。
以下代码演示了这些步骤:
VMR9VideoDesc VideoDesc;
DWORD dwNumModes = 0;
// Fill in the VideoDesc structure (not shown).
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, NULL);
if (SUCCEEDED(hr) && (dwNumModes != 0))
{
// Allocate an array for the GUIDs that identify the modes.
GUID *pModes = new GUID[dwNumModes];
if (pModes)
{
// Fill the array.
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, pModes);
if (SUCCEEDED(hr))
{
// Loop through each item and get the capabilities.
for (int i = 0; i < dwNumModes; i++)
{
VMR9DeinterlaceCaps Caps;
hr = pDeinterlace->GetDeinterlaceModeCaps(pModes + i,
&VideoDesc, &Caps);
if (SUCCEEDED(hr))
{
// Examine the Caps structure.
}
}
}
delete [] pModes;
}
}
现在,应用程序可以使用以下方法设置流的去隔行模式:
- SetDeinterlaceMode 方法设置首选模式。 使用 GUID_NULL 关闭反交错。
- SetDeinterlacePrefs 方法指定请求的模式不可用时的行为。
- GetDeinterlaceMode 方法返回你设置的首选模式。
- GetActualDeinterlaceMode 方法返回使用的实际模式,如果首选模式不可用,这可能是回退模式。
方法参考页提供了详细信息。
使用 VMR9VideoDesc 结构
在前面给出的过程中,第一步是使用视频流的说明填充 VMR9VideoDesc 结构。 首先获取视频流的媒体类型。 为此,可以在 VMR 筛选器的输入引脚上调用 IPin::ConnectionMediaType 。 然后确认视频流是否交错。 只能隔行扫描 VIDEOINFOHEADER2 格式。 如果格式类型为FORMAT_VideoInfo,则它必须是渐进式帧。 如果格式类型为FORMAT_VideoInfo2,检查AMINTERLACE_IsInterlaced标志的 dwInterlaceFlags 字段。 此标志的存在指示视频是交错的。
假设变量 pBMI 是指向格式块中 BITMAPINFOHEADER 结构的指针。 在 VMR9VideoDesc 结构中设置以下值:
dwSize:将此字段设置为
sizeof(VMR9VideoDesc)
。dwSampleWidth:将此字段设置为
pBMI->biWidth
。dwSampleHeight:将此字段设置为
abs(pBMI->biHeight)
。SampleFormat:此字段描述媒体类型的交错特征。 检查 VIDEOINFOHEADER2 结构中的 dwInterlaceFlags 字段,并将 SampleFormat 设置为等效VMR9_SampleFormat标志。 下面提供了用于执行此操作的帮助程序函数。
InputSampleFreq:此字段提供输入频率,可通过 VIDEOINFOHEADER2 结构中的 AvgTimePerFrame 字段计算。 在一般情况下,将 dwNumerator 设置为 10000000,并将 dwDenominator 设置为 AvgTimePerFrame。 但是,还可以针对某些已知帧速率检查:
每帧的平均时间 帧速率 (fps) 分子 分母 166833 59.94 (NTSC) 60000 1001 333667 29.97 (NTSC) 30000 1001 417188 23.97 (NTSC) 24000 1001 200000 50.00 (PAL) 50 1 400000 25.00 (PAL) 25 1 416667 24.00 (电影) 24 1 OutputFrameFreq:此字段提供输出频率,该频率可以根据 InputSampleFreq 值和输入流的交错特征进行计算:
- 将 OutputFrameFreq.dwDenominator 设置为 InputSampleFreq.dwDenominator。
- 如果输入视频是交错的,请将 OutputFrameFreq.dwNumerator 设置为 2 x InputSampleFreq.dwNumerator。 (取消交错后,帧速率为双倍。) 否则,将值设置为 InputSampleFreq.dwNumerator。
dwFourCC:将此字段设置为
pBMI->biCompression
。
以下帮助程序函数将 AMINTERLACE_X 标志转换为 VMR9_SampleFormat 值:
#define IsInterlaced(x) ((x) & AMINTERLACE_IsInterlaced)
#define IsSingleField(x) ((x) & AMINTERLACE_1FieldPerSample)
#define IsField1First(x) ((x) & AMINTERLACE_Field1First)
VMR9_SampleFormat ConvertInterlaceFlags(DWORD dwInterlaceFlags)
{
if (IsInterlaced(dwInterlaceFlags)) {
if (IsSingleField(dwInterlaceFlags)) {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldSingleEven;
}
else {
return VMR9_SampleFieldSingleOdd;
}
}
else {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldInterleavedEvenFirst;
}
else {
return VMR9_SampleFieldInterleavedOddFirst;
}
}
}
else {
return VMR9_SampleProgressiveFrame; // Not interlaced.
}
}