共用方式為


提供自訂配置器

[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngine,以及媒體基金會中的音訊/視訊擷取 取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayerIMFMediaEngine 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]

本節說明如何為過濾器提供自定義的分配器。 只會描述 IMemInputPin 連線,但 IAsyncReader 連線的步驟類似。

首先,為配置器定義C++類別。 您的配置器可以衍生自其中一個標準配置器類別、CBaseAllocatorCMemAllocator,或者您可以建立全新的配置器類別。 如果您建立新的類別,它必須公開 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)  
    {
        // 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::DecideAllocator 方法。 不過,請注意,這可能會限制輸出端子與特定過濾器的連接,因為其他過濾器也可能需要自己的自定義配置器。 第三個選項是切換順序:請先試用您的自定義配置器,然後再切換回另一個篩選的配置器。

協商分配器