[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayer、IMFMediaEngine和媒體基金會中的音訊/視訊擷取 取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayer、IMFMediaEngine 和 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]
影片混合轉譯器 (VMR) 支援硬體加速的反交錯,可改善交錯視訊的轉譯品質。 可用的確切功能取決於基礎硬體。 應用程式可以查詢硬體去交錯功能,並透過 IVMRDeinterlaceControl 介面 (VMR-7)或 IVMRDeinterlaceControl9 介面 (VMR-9)來設定去交錯偏好設定。 反交錯處理是依據每個數據流來執行。
VMR-7 與 VMR-9 之間的交錯行為有一個重要差異。 在圖形硬體不支援進階反交錯的系統上,VMR-7 可以退回到硬體覆疊,並指示其使用 BOB 樣式的反交錯。 在此情況下,雖然 VMR 報告每秒 30 帧,但影片實際上以每秒 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,請檢查 dwInterlaceFlags 字段是否有AMINTERLACE_IsInterlaced旗標。 此旗標的存在表示影片是交錯的。
假設 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.
}
}