手順 4. アロケーターのプロパティを設定する
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
これは、 変換フィルターの作成に関するチュートリアルの手順 4 です。
注意
この手順は、 CTransInPlaceFilter から派生したフィルターには必要ありません。
2 つのピンがメディアの種類に一致した後、接続のアロケーターを選択し、バッファー サイズやバッファー数などのアロケーター プロパティをネゴシエートします。
CTransformFilter クラスには、アップストリーム ピン接続用とダウンストリーム ピン接続用の 2 つのアロケーターがあります。 アップストリーム フィルターは、アップストリーム アロケーターを選択し、アロケーターのプロパティも選択します。 入力ピンは、アップストリーム フィルターが決定した内容を受け入れます。 この動作を変更する必要がある場合は、 CBaseInputPin::NotifyAllocator メソッドを オーバーライドします。
変換フィルターの出力ピンは、ダウンストリーム アロケーターを選択します。 それによって次の手順が実行されます。
- ダウンストリーム フィルターがアロケーターを提供できる場合、出力ピンはそのアロケーターを使用します。 それ以外の場合、出力ピンは新しいアロケーターを作成します。
- 出力ピンは、 IMemInputPin::GetAllocatorRequirements を呼び出すことによって、ダウンストリーム フィルターのアロケーター要件 (ある場合) を取得します。
- 出力ピンは、純粋仮想である変換フィルターの CTransformFilter::D ecideBufferSize メソッドを呼び出します。 このメソッドのパラメーターは、アロケーターへのポインターであり、ダウンストリーム フィルターの要件を持つ ALLOCATOR_PROPERTIES 構造体です。 ダウンストリーム フィルターにアロケーター要件がない場合、構造体はゼロになります。
- DecideBufferSize メソッドでは、派生クラスは IMemAllocator::SetProperties を呼び出してアロケーター プロパティを設定します。
一般に、派生クラスは、出力形式、ダウンストリーム フィルターの要件、およびフィルター独自の要件に基づいてアロケーター プロパティを選択します。 ダウンストリーム フィルターの要求と互換性のあるプロパティを選択してみてください。 そうしないと、ダウンストリーム フィルターによって接続が拒否される可能性があります。
次の例では、RLE エンコーダーによってバッファー サイズ、バッファーアラインメント、バッファー数の最小値が設定されます。 プレフィックスには、ダウンストリーム フィルターが要求した値が使用されます。 プレフィックスは通常 0 バイトですが、一部のフィルターでは必要です。 たとえば、 AVI Mux フィルターでは、プレフィックスを使用して RIFF ヘッダーを書き込みます。
HRESULT CRleFilter::DecideBufferSize(
IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp)
{
AM_MEDIA_TYPE mt;
HRESULT hr = m_pOutput->ConnectionMediaType(&mt);
if (FAILED(hr))
{
return hr;
}
ASSERT(mt.formattype == FORMAT_VideoInfo);
BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);
pProp->cbBuffer = DIBSIZE(*pbmi) * 2;
if (pProp->cbAlign == 0)
{
pProp->cbAlign = 1;
}
if (pProp->cBuffers == 0)
{
pProp->cBuffers = 1;
}
// Release the format block.
FreeMediaType(mt);
// Set allocator properties.
ALLOCATOR_PROPERTIES Actual;
hr = pAlloc->SetProperties(pProp, &Actual);
if (FAILED(hr))
{
return hr;
}
// Even when it succeeds, check the actual result.
if (pProp->cbBuffer > Actual.cbBuffer)
{
return E_FAIL;
}
return S_OK;
}
アロケーターが要求と正確に一致しない場合があります。 したがって、 SetProperties メソッドは、実際の結果を個別の ALLOCATOR_PROPERTIES 構造体 (前の例では Actual パラメーター) で返します。 SetProperties が成功した場合でも、フィルターの最小要件を満たすように結果をチェックする必要があります。
カスタム アロケーター
既定では、すべてのフィルター クラスでアロケーターに CMemAllocator クラスが使用されます。 このクラスは、( VirtualAlloc を使用して) クライアント プロセスの仮想アドレス空間からメモリを割り当てます。 フィルターで DirectDraw サーフェスなどの他の種類のメモリを使用する必要がある場合は、カスタム アロケーターを実装できます。 CBaseAllocator クラスを使用することも、まったく新しいアロケーター クラスを記述することもできます。 フィルターにカスタム アロケーターがある場合は、アロケーターを使用するピンに応じて、次のメソッドをオーバーライドします。
- 入力ピン: CBaseInputPin::GetAllocator と CBaseInputPin::NotifyAllocator。
- 出力ピン: CBaseOutputPin::D ecideAllocator。
他のフィルターがカスタム アロケーターを使用した接続を拒否した場合、フィルターは接続に失敗するか、他のフィルターのアロケーターと接続できます。 後者の場合は、アロケーターの種類を示す内部フラグを設定する必要がある場合があります。 この方法の例については、「 CDrawImage クラス」を参照してください。
次へ: 手順 5.イメージを変換します。
関連トピック