Poskytnutí vlastního alokátoru

[Funkce přidružená k této stránce DirectShow je starší funkce. Byla nahrazena MediaPlayer, MMFMediaEnginea Audio/Video Capture v Media Foundation. Tyto funkce jsou optimalizované pro Windows 10 a Windows 11. Microsoft důrazně doporučuje, aby nový kód používal MediaPlayer, MMFMediaEngine a Audio/Video Capture v Media Foundation místo DirectShow, pokud je to možné. Microsoft navrhuje, aby se stávající kód, který používá starší rozhraní API, přepsal, aby se nová rozhraní API používala, pokud je to možné.]

Tato část popisuje, jak poskytnout vlastní alokátor filtru. Popisují se pouze připojení IMemInputPin, ale postup připojení IAsyncReader je podobný.

Nejprve definujte třídu C++ pro alokátor. Váš alokátor může odvodit z jedné ze standardních tříd alokátoru, CBaseAllocator nebo CMemAllocatornebo můžete vytvořit zcela novou třídu alokátoru. Pokud vytvoříte novou třídu, musí vystavit rozhraní IMemAllocator.

Zbývající kroky závisí na tom, zda váš alokátor patří k vstupnímu pinu nebo výstupnímu pinu vašeho filtru. Vstupní piny hrají jinou roli než výstupní piny během fáze vyjednávání alokátoru, protože výstupní pin nakonec vybere alokátor.

Poskytnutí vlastního alokátoru pro vstupní pin

Pokud chcete poskytnout alokátor pro vstupní pin, přepište metodu vstupního pinu CBaseInputPin::GetAllocator. V rámci této metody zkontrolujte m_pAllocator členské proměnné. Pokud tato proměnná neníNULL, znamená to, že pro toto připojení již byl vybrán alokátor, takže metoda GetAllocator musí vrátit ukazatel na tento alokátor. Pokud je m_pAllocatorNULL, znamená to, že alokátor nebyl vybrán, takže metoda GetAllocator by měla vrátit ukazatel na upřednostňovaný alokátor vstupního pinu. V takovém případě vytvořte instanci svého vlastního alokátoru a vraťte ukazatel IMemAllocator. Následující kód ukazuje, jak implementovat metodu 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);
}

Když upstreamový filtr vybere alokátor, zavolá metoda vstupního pinu IMemInputPin::NotifyAllocator. Přepište metodu CBaseInputPin::NotifyAllocator ke kontrole vlastností alokátoru. V některých případech může vstupní pin odmítnout alokátor, pokud není vaším vlastním alokátorem, což však může způsobit selhání celého spojení pinu.

poskytnutí vlastního alokátoru pro výstupní pin

Pokud chcete poskytnout alokátor pro výstupní pin, přepište CBaseOutputPin::InitAllocator metodu vytvoření instance vašeho alokátoru:

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);
}

Ve výchozím nastavení třída CBaseOutputPin nejprve požaduje alokátor ze vstupního pinu. Pokud tento alokátor není vhodný, výstupní kolík vytvoří vlastní alokátor. Pokud chcete vynutit pro připojení využít vlastního alokátoru, přepište metodu CBaseOutputPin::DecideAllocator. Mějte ale na paměti, že to může zabránit výstupnímu pinu v připojení k určitým filtrům, protože druhý filtr může také vyžadovat svůj vlastní alokátor. Třetí možností je přepnout pořadí: Nejprve zkuste vlastní alokátor a pak se vraťte k alokátoru druhého filtru.

Vyjednávání Alokátorů