Deinterlace の基本設定の設定
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
Video Mixing Renderer (VMR) では、ハードウェアアクセラレータによるデインターレースがサポートされています。これにより、インターレースされたビデオのレンダリング品質が向上します。 使用できる正確な機能は、基になるハードウェアによって異なります。 アプリケーションは、ハードウェアのインターレース解除機能を照会し、 IVMRDeinterlaceControl インターフェイス (VMR-7) または IVMRDeinterlaceControl9 インターフェイス (VMR-9) を使用して、インターレース解除の基本設定を設定できます。 インターレース解除は、ストリームごとに実行されます。
VMR-7 と VMR-9 の間のインターレース動作には重要な違いが 1 つあります。 グラフィックス ハードウェアが高度なインターレース解除をサポートしていないシステムでは、VMR-7 はハードウェア オーバーレイにフォールバックし、BOB スタイルのデインターレースを使用するように指示できます。 この場合、VMR は 30fps を報告していますが、ビデオは実際には 1 秒あたり 60 フリップでレンダリングされています。
ハードウェア オーバーレイを使用する VMR-7 の場合を除き、インターレース解除は VMR のミキサーによって実行されます。 ミキサーは、DirectX ビデオ アクセラレーション (DXVA) デインターレース デバイス ドライバー インターフェイス (DDI) を使用して、デインターレースを実行します。 この DDI はアプリケーションで呼び出すことができません。また、アプリケーションは VMR のインターレース解除機能を置き換えることはできません。 ただし、アプリケーションでは、このセクションで説明するように、目的のインターレース解除モードを選択できます。
注意
このセクションでは 、IVMRDeinterlaceControl9 メソッドについて説明しますが、VMR-7 のバージョンはほぼ同じです。
ビデオ ストリームのインターレース解除機能を取得するには、次の操作を行います。
- VMR9VideoDesc 構造体にビデオ ストリームの説明を入力します。 この構造を入力する方法の詳細については、後で説明します。
- 構造体を IVMRDeinterlaceControl9::GetNumberOfDeinterlaceModes メソッドに渡します。 メソッドを 2 回呼び出します。 最初の呼び出しは、ハードウェアが指定した形式でサポートするデインターレース モードの数を返します。 このサイズの GUID の配列を割り当て、もう一度 メソッドを呼び出して、配列のアドレスを渡します。 2 番目の呼び出しでは、配列に GUID が入力されます。 各 GUID は、1 つのインターレース解除モードを識別します。
- 特定のモードの上限を取得するには、 IVMRDeinterlaceControl9::GetDeinterlaceModeCaps メソッドを呼び出します。 配列の GUID の 1 つと共に、同じ VMR9VideoDesc 構造体を渡します。 メソッドは 、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 が format ブロック内の 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 に設定します。 (インターレース解除後、フレーム レートは 2 倍になります)。それ以外の場合は、値を 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.
}
}