Share via


Fourniture d’un outil d’allocation personnalisé

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement au nouveau code d’utiliser MediaPlayer, IMFMediaEngine et La capture audio/vidéo dans Media Foundation au lieu de DirectShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Cette section explique comment fournir un allocateur personnalisé pour un filtre. Seules les connexions IMemInputPin sont décrites, mais les étapes pour une connexion IAsyncReader sont similaires.

Tout d’abord, définissez une classe C++ pour l’allocateur. Votre allocateur peut dériver de l’une des classes d’allocator standard, CBaseAllocator ou CMemAllocator, ou vous pouvez créer une classe d’allocator entièrement nouvelle. Si vous créez une classe, elle doit exposer l’interface IMemAllocator .

Les étapes restantes varient selon que votre allocateur appartient à une broche d’entrée ou à une broche de sortie sur votre filtre. Les broches d’entrée jouent un rôle différent des broches de sortie pendant la phase de négociation de l’allocateur, car la broche de sortie sélectionne finalement l’allocateur.

Fourniture d’un allocateur personnalisé pour une broche d’entrée

Pour fournir un allocateur pour une broche d’entrée, remplacez la méthode CBaseInputPin::GetAllocator de la broche d’entrée. Dans cette méthode, case activée la variable membre m_pAllocator. Si cette variable n’est pas NULL, cela signifie que l’allocateur a déjà été sélectionné pour cette connexion. La méthode GetAllocator doit donc retourner un pointeur vers cet allocateur. Si m_pAllocator a la valeur NULL, cela signifie que l’allocateur n’a pas été sélectionné. La méthode GetAllocator doit donc renvoyer un pointeur vers l’allocateur préféré de la broche d’entrée. Dans ce cas, créez une instance de votre allocateur personnalisé et retournez son pointeur IMemAllocator. Le code suivant montre comment implémenter la méthode 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);
}

Lorsque le filtre amont sélectionne un allocateur, il appelle la méthode IMemInputPin::NotifyAllocator de la broche d’entrée. Remplacez la méthode CBaseInputPin::NotifyAllocator pour case activée les propriétés de l’allocator. Dans certains cas, le code pin d’entrée peut rejeter l’allocateur s’il ne s’agit pas de votre allocateur personnalisé, même si cela peut entraîner l’échec de l’ensemble de la connexion de broche.

Fourniture d’un allocateur personnalisé pour une broche de sortie

Pour fournir un allocateur pour une broche de sortie, remplacez la méthode CBaseOutputPin::InitAllocator pour créer une instance de votre allocator :

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

Par défaut, la classe CBaseOutputPin demande d’abord un allocator à partir de la broche d’entrée. Si cet allocateur ne convient pas, la broche de sortie crée son propre allocateur. Pour forcer la connexion à utiliser votre allocateur personnalisé, remplacez la méthode CBaseOutputPin::D ecideAllocator . Toutefois, sachez que cela peut empêcher votre broche de sortie de se connecter avec certains filtres, car l’autre filtre peut également nécessiter son propre allocateur personnalisé. Une troisième option consiste à changer d’ordre : essayez d’abord votre outil d’allocation personnalisé, puis revenez à l’allocateur de l’autre filtre.

Négociation des allocateurs