Delen via


Een aangepaste allocator bieden

[De functie die is gekoppeld aan deze pagina, DirectShow, is een verouderde functie. Het is vervangen door MediaPlayer, IMFMediaEngineen Audio/Video Capture in Media Foundation. Deze functies zijn geoptimaliseerd voor Windows 10 en Windows 11. Microsoft raadt ten zeerste aan om nieuwe code te gebruiken MediaPlayer, IMFMediaEngine en Audio/Video Capture in Media Foundation in plaats van DirectShow, indien mogelijk. Microsoft stelt voor dat bestaande code die gebruikmaakt van de verouderde API's, indien mogelijk opnieuw worden geschreven om de nieuwe API's te gebruiken.]

In deze sectie wordt beschreven hoe u een aangepaste allocator voor een filter opgeeft. Alleen IMemInputPin--verbindingen worden beschreven, maar de stappen voor een IAsyncReader verbinding zijn vergelijkbaar.

Definieer eerst een C++-klasse voor de allocator. Uw allocator kan worden afgeleid van een van de standaard allocatorklassen, CBaseAllocator of CMemAllocator, of u kunt een geheel nieuwe allocatorklasse maken. Als u een nieuwe klasse maakt, moet deze de IMemAllocator-interface beschikbaar maken.

De resterende stappen zijn afhankelijk van of uw allocator deel uitmaakt van een invoerpin of een uitvoerpin op uw filter. Invoerpinnen spelen een andere rol dan uitvoerpinnen tijdens de onderhandelingsfase van de allocator, omdat de uitvoerpin uiteindelijk de allocator selecteert.

Een aangepaste allocator opgeven voor een invoerpincode

Als u een allocator wilt opgeven voor een invoerpin, overschrijft u de CBaseInputPin::GetAllocator methode. Controleer in deze methode de variabele m_pAllocator lid. Als deze variabele niet-NULL-is, betekent dit dat de allocator al is geselecteerd voor deze verbinding. De methode GetAllocator moet dus een aanwijzer naar die allocator retourneren. Als m_pAllocatorNULLis, betekent dit dat de allocator niet is geselecteerd, dus de methode GetAllocator moet een pointer retourneren naar de voorkeurs-allocator van de invoerpin. Maak in dat geval een exemplaar van uw aangepaste allocator en retourneer de bijbehorende IMemAllocator aanwijzer. De volgende code laat zien hoe u de methode GetAllocator implementeert:

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

Wanneer het upstream-filter een allocator selecteert, roept het de methode IMemInputPin::NotifyAllocator aan. Overschrijf de methode CBaseInputPin::NotifyAllocator om de allocatoreigenschappen te controleren. In sommige gevallen kan de invoerpin de allocator weigeren als het geen door u aangepaste allocator is, hoewel dit ertoe kan leiden dat de gehele pinverbinding mislukt.

Een aangepaste allocator opgeven voor een uitvoerpincode

Als u een allocator wilt opgeven voor een uitvoerpin, overschrijdt u de CBaseOutputPin::InitAllocator methode om een instantie van de allocator te maken.

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

De CBaseOutputPin klasse vraagt standaard eerst een allocator aan bij de invoerpin. Als deze allocator niet geschikt is, maakt de uitvoerpin een eigen allocator. Om af te dwingen dat de verbinding gebruik maakt van uw aangepaste allocator, overschrijft u de methode CBaseOutputPin::DecideAllocator. Houd er echter rekening mee dat dit kan voorkomen dat uw uitvoerpin verbinding maakt met bepaalde filters, omdat het andere filter mogelijk ook een eigen aangepaste allocator vereist. Een derde optie is om de volgorde te wijzigen: Probeer eerst de aangepaste allocator en ga vervolgens terug naar de allocator van het andere filter.

Onderhandelen over toewijzers