次の方法で共有


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

ここでは、フィルタのカスタム アロケータを提供する方法について説明する。IMemInputPin 接続についてのみ説明するが、IAsyncReader 接続の手順も同様である。

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

残りの手順は、アロケータがフィルタの入力ピンと出力ピンのどちらに属するかによって異なる。入力ピンはアロケータの調整時期に出力ピンとは異なる役割を演じる。これは、最終的には出力ピンがアロケータを選択するためである。

入力ピン用のカスタム アロケータの提供

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

STDMETHODIMP CMyInputPin::GetAllocator(IMemAllocator **ppAllocator)
{
    CheckPointer(ppAllocator, E_POINTER);
    if (m_pAllocator)  
    {
        // 既にアロケータがあるため、そのアロケータを返す。
        *ppAllocator = m_pAllocator;
        (*ppAllocator)->AddRef();
        return S_OK;
    }
    // アロケータがないため、カスタム アロケータを提示する。ここでのコードの細部は、
    // カスタム アロケータのクラス定義によって異なる。
    HRESULT hr = S_OK;
    CMyAllocator *pAlloc = new CMyAllocator(&hr);
    if (!pAlloc)
    {
        return E_OUTOFMEMORY;
    }
    if (FAILED(hr))
    {
        delete pAlloc;
        return hr;
    }
    // 呼び出し元に IMemAllocator インターフェイスを返す。
    return pAlloc->QueryInterface(IID_IMemAllocator, (void**)ppAllocator);
}

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

出力ピン用のカスタム アロケータの提供

出力ピン用のアロケータを提供するには、CBaseOutputPin::InitAllocator をオーバーライドしてアロケータのインスタンスを作成する。

HRESULT MyOutputPin::InitAllocator(IMemAllocator **ppAlloc)
{
    HRESULT hr = S_OK;
    CMyAllocator *pAlloc = new CMyAllocator(&hr);
    if (!pAlloc)
    {
        return E_OUTOFMEMORY;
    }
    if (FAILED(hr))
    {
        delete pAlloc;
        return hr;
    }
    // IMemAllocator インターフェイスを返す。
    return pAlloc->QueryInterface(IID_IMemAllocator, void**)ppAllocator);}
}

デフォルトでは、CBaseOutputPin クラスは最初に入力ピンからアロケータを要求する。そのアロケータが適切ではない場合、出力ピンは独自のアロケータを作成する。接続でカスタム アロケータを強制的に使うようにするには、CBaseOutputPin::DecideAllocator メソッドをオーバーライドする。しかし、その場合、出力ピンが一部のフィルタに接続しなくなる可能性がある点に注意すること。他のフィルタも独自のカスタム アロケータを必要とすることがあるためである。

参照