次の方法で共有


手順 4. アロケーターのプロパティを設定する

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayerIMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]

これは、 変換フィルターの作成に関するチュートリアルの手順 4 です。

注意

この手順は、 CTransInPlaceFilter から派生したフィルターには必要ありません。

 

2 つのピンがメディアの種類に一致した後、接続のアロケーターを選択し、バッファー サイズやバッファー数などのアロケーター プロパティをネゴシエートします。

CTransformFilter クラスには、アップストリーム ピン接続用とダウンストリーム ピン接続用の 2 つのアロケーターがあります。 アップストリーム フィルターは、アップストリーム アロケーターを選択し、アロケーターのプロパティも選択します。 入力ピンは、アップストリーム フィルターが決定した内容を受け入れます。 この動作を変更する必要がある場合は、 CBaseInputPin::NotifyAllocator メソッドを オーバーライドします。

変換フィルターの出力ピンは、ダウンストリーム アロケーターを選択します。 それによって次の手順が実行されます。

  1. ダウンストリーム フィルターがアロケーターを提供できる場合、出力ピンはそのアロケーターを使用します。 それ以外の場合、出力ピンは新しいアロケーターを作成します。
  2. 出力ピンは、 IMemInputPin::GetAllocatorRequirements を呼び出すことによって、ダウンストリーム フィルターのアロケーター要件 (ある場合) を取得します。
  3. 出力ピンは、純粋仮想である変換フィルターの CTransformFilter::D ecideBufferSize メソッドを呼び出します。 このメソッドのパラメーターは、アロケーターへのポインターであり、ダウンストリーム フィルターの要件を持つ ALLOCATOR_PROPERTIES 構造体です。 ダウンストリーム フィルターにアロケーター要件がない場合、構造体はゼロになります。
  4. 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 クラスを使用することも、まったく新しいアロケーター クラスを記述することもできます。 フィルターにカスタム アロケーターがある場合は、アロケーターを使用するピンに応じて、次のメソッドをオーバーライドします。

他のフィルターがカスタム アロケーターを使用した接続を拒否した場合、フィルターは接続に失敗するか、他のフィルターのアロケーターと接続できます。 後者の場合は、アロケーターの種類を示す内部フラグを設定する必要がある場合があります。 この方法の例については、「 CDrawImage クラス」を参照してください。

次へ: 手順 5.イメージを変換します

DirectShow フィルターの作成