Freigeben über


Bereitstellen einer benutzerdefinierten Zuordnung

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde durch MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation ersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code nach Möglichkeit MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet. Microsoft schlägt vor, vorhandenen Code, der die Legacy-APIs verwendet, um nach Möglichkeit die neuen APIs zu verwenden.]

In diesem Abschnitt wird beschrieben, wie Sie eine benutzerdefinierte Zuweisung für einen Filter bereitstellen. Es werden nur IMemInputPin-Verbindungen beschrieben, aber die Schritte für eine IAsyncReader-Verbindung sind ähnlich.

Definieren Sie zunächst eine C++-Klasse für die Zuordnung. Ihr Allocator kann von einer der Standardzuordnungsklassen CBaseAllocator oder CMemAllocator abgeleitet werden, oder Sie können eine völlig neue Zuordnungsklasse erstellen. Wenn Sie eine neue Klasse erstellen, muss sie die IMemAllocator-Schnittstelle verfügbar machen.

Die restlichen Schritte hängen davon ab, ob Ihr Zuteilungsstift zu einem Eingabenadel oder einem Ausgabestift des Filters gehört. Eingabepins spielen während der Aushandlungsphase des Zuteilungsvorgangs eine andere Rolle als Ausgabepins, da der Ausgabepin letztendlich den Zuteilungsstift auswählt.

Bereitstellen einer benutzerdefinierten Zuordnung für eine Eingabenadel

Um einen Zuteilungsgeber für einen Eingabenadel bereitzustellen, überschreiben Sie die CBaseInputPin::GetAllocator-Methode des Eingabenadels. Überprüfen Sie innerhalb dieser Methode die m_pAllocator Membervariable. Wenn diese Variable nicht NULL ist, bedeutet dies, dass der Zuweisungsator bereits für diese Verbindung ausgewählt wurde, sodass die GetAllocator-Methode einen Zeiger auf diesen Zuweisungsator zurückgeben muss. Wenn m_pAllocatorNULL ist, bedeutet dies, dass der Zuweisungsator nicht ausgewählt wurde, sodass die GetAllocator-Methode einen Zeiger auf den bevorzugten Zuordnungsgeber des Eingabenadels zurückgeben sollte. Erstellen Sie in diesem Fall eine instance Ihrer benutzerdefinierten Zuordnung, und geben Sie den IMemAllocator-Zeiger zurück. Der folgende Code zeigt, wie Die GetAllocator-Methode implementiert wird:

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

Wenn der Upstream-Filter eine Zuordnung auswählt, ruft er die IMemInputPin::NotifyAllocator-Methode des Eingabenadels auf. Überschreiben Sie die CBaseInputPin::NotifyAllocator-Methode , um die Zuordnungseigenschaften zu überprüfen. In einigen Fällen kann der Eingabenadel die Zuweisung ablehnen, wenn es sich nicht um Ihren benutzerdefinierten Zuordnungsgeber handelt, obwohl dies dazu führen kann, dass die gesamte Pinverbindung fehlschlägt.

Bereitstellen einer benutzerdefinierten Zuordnung für einen Ausgabenadel

Um einen Zuteilungsgeber für einen Ausgabepin bereitzustellen, überschreiben Sie die CBaseOutputPin::InitAllocator-Methode, um eine instance Ihrer Zuordnung zu erstellen:

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

Standardmäßig fordert die CBaseOutputPin-Klasse zuerst einen Zuteilungsvorgang vom Eingabenadel an. Wenn dieser Zuweisungsgeber nicht geeignet ist, erstellt der Ausgabenadel einen eigenen Zuteilungsgeber. Um zu erzwingen, dass die Verbindung Ihre benutzerdefinierte Zuweisung verwendet, überschreiben Sie die CBaseOutputPin::D ecideAllocator-Methode . Beachten Sie jedoch, dass dies verhindern kann, dass Ihr Ausgabepin eine Verbindung mit bestimmten Filtern herstellt, da der andere Filter möglicherweise auch einen eigenen benutzerdefinierten Zuteilungsgeber erfordert. Eine dritte Option besteht darin, die Reihenfolge zu ändern: Versuchen Sie zuerst Ihren benutzerdefinierten Zuteilungsanbieter, und greifen Sie dann auf den Zuordnungsanbieter des anderen Filters zurück.

Aushandeln von Zuteilungen