次の方法で共有


カスタム アロケーターの提供

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

このセクションでは、フィルターのカスタム アロケーターを提供する方法について説明します。 IMemInputPin 接続のみが説明されていますが、IAsyncReader 接続の手順は似ています。

まず、アロケーターの C++ クラスを定義します。 アロケーターは、標準のアロケーター クラス ( CBaseAllocator または CMemAllocator) から派生することも、まったく新しいアロケーター クラスを作成することもできます。 新しいクラスを作成する場合は、 IMemAllocator インターフェイスを公開する必要があります。

残りの手順は、アロケーターがフィルターの入力ピンと出力ピンのどちらに属しているかによって異なります。 入力ピンは、アロケーター ネゴシエーション フェーズ中に出力ピンとは異なる役割を果たします。これは、出力ピンが最終的にアロケーターを選択するためです。

入力ピンにカスタム アロケーターを提供する

入力ピンのアロケーターを指定するには、入力ピンの CBaseInputPin::GetAllocator メソッドを オーバーライドします。 このメソッド内で、m_pAllocatorメンバー変数をチェックします。 この変数が NULL 以外の場合は、この接続に対してアロケーターが既に選択されているため、 GetAllocator メソッドはそのアロケーターへのポインターを返す必要があります。 m_pAllocatorNULL の場合は、アロケーターが選択されていないことを意味するため、GetAllocator メソッドは入力ピンの優先アロケーターへのポインターを返す必要があります。 その場合は、カスタム アロケーターのインスタンスを作成し、その IMemAllocator ポインターを 返します。 次のコードは 、GetAllocator メソッドを実装する方法を示しています。

STDMETHODIMP CMyInputPin::GetAllocator(IMemAllocator **ppAllocator)
{
    CheckPointer(ppAllocator, E_POINTER);
    if (m_pAllocator)  
    {
        // We already have an allocator, so return that one.
        *ppAllocator = m_pAllocator;
        (*ppAllocator)->AddRef();
        return S_OK;
    }

    // No allocator yet, so propose our custom allocator. The exact code
    // here will depend on your custom allocator class definition.
    HRESULT hr = S_OK;
    CMyAllocator *pAlloc = new CMyAllocator(&hr);
    if (!pAlloc)
    {
        return E_OUTOFMEMORY;
    }
    if (FAILED(hr))
    {
        delete pAlloc;
        return hr;
    }

    // Return the IMemAllocator interface to the caller.
    return pAlloc->QueryInterface(IID_IMemAllocator, (void**)ppAllocator);
}

アップストリーム フィルターは、アロケーターを選択すると、入力ピンの IMemInputPin::NotifyAllocator メソッドを呼び出します。 CBaseInputPin::NotifyAllocator メソッドをオーバーライドして、アロケーター プロパティをチェックします。 場合によっては、入力ピンがカスタム アロケーターでない場合はアロケーターを拒否することがありますが、これによりピン接続全体が失敗する可能性があります。

出力ピンにカスタム アロケーターを提供する

出力ピンのアロケーターを指定するには、 CBaseOutputPin::InitAllocator メソッドをオーバーライドして、アロケーターのインスタンスを作成します。

HRESULT MyOutputPin::InitAllocator(IMemAllocator **ppAllocator)
{
    HRESULT hr = S_OK;
    CMyAllocator *pAlloc = new CMyAllocator(&hr);
    if (!pAlloc)
    {
        return E_OUTOFMEMORY;
    }

    if (FAILED(hr))
    {
        delete pAlloc;
        return hr;
    }

    // Return the IMemAllocator interface.
    return pAlloc->QueryInterface(IID_IMemAllocator, (void**)ppAllocator);
}

既定では、 CBaseOutputPin クラスは最初に入力ピンからアロケーターを要求します。 そのアロケーターが適していない場合は、出力ピンによって独自のアロケーターが作成されます。 接続でカスタム アロケーターを強制的に使用するには、 CBaseOutputPin::D ecideAllocator メソッドを オーバーライドします。 ただし、他のフィルターには独自のカスタム アロケーターが必要になる場合があるため、これにより、出力ピンが特定のフィルターに接続できなくなる可能性があることに注意してください。 3 番目のオプションは、順序を切り替える方法です。最初にカスタム アロケーターを試してから、他のフィルターのアロケーターにフォールバックします。

アロケーターのネゴシエート