ビデオ圧縮プロパティの設定
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
ビデオ圧縮フィルターは、出力ピンで IAMVideoCompression インターフェイスをサポートできます。 このインターフェイスを使用して、キー フレーム レート、キー フレームあたりの予測 (P) フレーム数、相対的な圧縮品質などの圧縮プロパティを設定します。
まず、 IBaseFilter::EnumPins メソッドを呼び出してフィルターの出力ピンを検索し、インターフェイスのピンに対してクエリを実行します。 一部のフィルターでは、インターフェイスがまったくサポートされない場合があります。 他のユーザーはインターフェイスを公開できますが、すべての圧縮プロパティをサポートしているわけではありません。 サポートされているプロパティを確認するには、 IAMVideoCompression::GetInfo を呼び出します。 このメソッドは、いくつかの情報を返します。
- 一連の機能フラグ
- 説明的な文字列とバージョン番号の文字列
- キー フレーム レート、P フレーム レート、品質の既定値 (サポートされている場合)
メソッドの構文は次のとおりです。
hr = pCompress->GetInfo(pszVersion, &cbVersion, pszDesc, &cbDesc,
&lKeyFrame, &lPFrame, &dblQuality, &lCap);
pszVersion パラメーターと pszDesc パラメーターは、バージョン文字列と説明文字列を受け取るワイド文字バッファーです。 cbVersion パラメーターと cbDesc パラメーターは、必要なバッファー サイズをバイト単位で受け取ります (文字ではありません)。 lKeyFrame、lPFrame、および dblQuality パラメーターは、キー フレーム レート、P フレーム レート、品質の既定値を受け取ります。 品質は、0.0 から 1.0 までの浮動小数点数として表されます。 lCap パラメーターは、CompressionCaps 列挙型によって定義される機能フラグのビットごとの OR を受け取ります。
これらのパラメーターは NULL にすることができます。この 場合、メソッドはそのパラメーターを無視します。 たとえば、バージョンと説明の文字列のバッファーを割り当てるには、最初に、最初のパラメーターと 3 番目のパラメーターで NULL を 指定して メソッドを呼び出します。 cbVersion と cbDesc の戻り値を使用してバッファーを割り当て、メソッドをもう一度呼び出します。
int cbVersion, cbDesc; // Size in bytes, not characters!
hr = pCompress->GetInfo(0, &cbVersion, 0, &cbDesc, 0, 0, 0, 0);
if (SUCCEEDED(hr))
{
WCHAR *pszVersion = new WCHAR[cbVersion/2]; // Wide character = 2 bytes
WCHAR *pszDesc = new WCHAR[cbDesc/2];
hr = pCompress->GetInfo(pszVersion, 0, pszDesc, 0, 0, 0, 0, 0);
}
lCap の値は、フィルターでサポートされているその他の IAMVideoCompression メソッドを示します。 たとえば、 lCap に CompressionCaps_CanKeyFrame フラグが含まれている場合は、 IAMVideoCompression::get_KeyFrameRate を呼び出してキーフレーム レートを取得し、 IAMVideoCompression::p ut_KeyFrameRate を呼び出してキーフレーム レートを設定できます。 負の値は、 IAMVideoCompression::GetInfo から取得した既定値がフィルターで使用されることを示します。 次に例を示します。
if (lCap & CompressionCaps_CanKeyFrame)
{
hr = pCompress->get_KeyFrameRate(&lKeyFrame);
if (FAILED(hr) || lKeyFrame < 0)
{
lKeyFrame = lDefaultKeyFrame; // From GetInfo.
}
}
次のコード例では、出力ピンで IAMVideoCompression インターフェイスの検索を試みます。 成功すると、圧縮プロパティの既定値と実際の値が取得されます。
HRESULT hr = E_FAIL;
IEnumPins *pEnum = NULL;
IPin *pPin = NULL;
IAMVideoCompression *pCompress = NULL;
// Find the pin that supports IAMVideoCompression (if any).
pFilter->EnumPins(&pEnum);
while (S_OK == pEnum->Next(1, &pPin, NULL))
{
hr = pPin->QueryInterface(IID_IAMVideoCompression, (void**)&pCompress);
pPin->Release();
if (SUCCEEDED(hr)) // Found the interface.
{
break;
}
}
if (SUCCEEDED(hr))
{
long lCap; // Capability flags
long lKeyFrame, lPFrame; // Real values
double m_Quality;
long lKeyFrameDef, lPFrameDef; // Default values
double QualityDef;
// Get default values and capabilities.
hr = pCompress->GetInfo(0, 0, 0, 0, &KeyFrameDef, &lPFrameDef,
&QualityDef, &lCap);
if (SUCCEEDED(hr))
{
// Get actual values where possible.
if (lCap & CompressionCaps_CanKeyFrame)
{
hr = pCompress->get_KeyFrameRate(&lKeyFrame);
if (FAILED(hr) || lKeyFrame < 0)
lKeyFrame = lKeyFrameDef;
}
if (lCap & CompressionCaps_CanBFrame)
{
hr = pCompress->get_PFramesPerKeyFrame(&lPFrame);
if (FAILED(hr) || lPFrame < 0)
lPFrame = lPFrameDef;
}
if (lCap & CompressionCaps_CanQuality)
{
hr = pCompress->get_Quality(&Quality);
if (FAILED(hr) || Quality < 0)
Quality = QualityDef;
}
}
}
注意
ICaptureGraphBuilder2 インターフェイスを使用してグラフを作成する場合は、IBaseFilter::EnumPins を使用する代わりに ICaptureGraphBuilder2::FindInterface を呼び出して IAMVideoCompression インターフェイスを取得できます。 FindInterface メソッドは、グラフ内のフィルターとピンを検索して、指定したインターフェイスを検索するヘルパー メソッドです。