Dela via


Anpassade topologiinläsare

När ett program köar en partiell topologi i mediesessionen använder mediasessionen en topologiinläsare för att lösa topologin. MediaSessionen använder som standard Media Foundation-implementeringen av topologiinläsaren, men du kan även tillhandahålla en anpassad implementering. Detta ger dig mer kontroll över den slutliga topologin. En anpassad topologiinläsare måste implementera gränssnittet IMFTopoLoader.

Om du vill ange en anpassad topologiinläsare i mediasessionen gör du följande:

  1. Skapa ett tomt attributarkiv genom att anropa MFCreateAttributes.
  2. Ange attributet MF_SESSION_TOPOLOADER i attributarkivet. Värdet för attributet är CLSID för din anpassade inläsare.
  3. Anropa MFCreateMediaSession för att skapa mediesessionen för oskyddat innehåll, eller MFCreatePMPMediaSession för att skapa mediesessionen i den skyddade mediesökvägen (PMP).

Not

Om du vill använda en anpassad topologiinläsare i PMP måste topologiinläsaren vara en betrodd komponent. Mer information finns i Skyddad mediesökväg.

 

Följande kod visar hur du anger en anpassad topologiinläsare på mediesessionen.

HRESULT CreateSession_CustomTopoLoader(REFCLSID clsid, IMFMediaSession **ppSession)
{
    *ppSession = NULL;

    IMFMediaSession *pSession = NULL;
    IMFAttributes *pConfig = NULL;

    // Create an attribute store to configure the media session.
    HRESULT hr = MFCreateAttributes(&pConfig, 1);

    // Set the CLSID of the custom topology loader.
    if (SUCCEEDED(hr))
    {
        hr = pConfig->SetGUID(MF_SESSION_TOPOLOADER, clsid);
    }

    // Create the media session.
    if (SUCCEEDED(hr))
    {
        hr = MFCreateMediaSession(pConfig, &pSession);
    }

    // Return the pointer to the caller.
    if (SUCCEEDED(hr))
    {
        *ppSession = pSession;
        (*ppSession)->AddRef();
    }

    SafeRelease(&pSession);
    SafeRelease(&pConfig);

    return hr;
}

Det är inte nödvändigt att implementera hela topologiinläsningsalgoritmen i topologiinläsaren. Alternativt kan du omsluta mediastiftelsens standardtopologiinläsare. I implementeringen av IMFTopoLoader::Load-metoden ändrar du topologin efter behov och skickar den ändrade topologin till standardtopologiinläsaren. Sedan slutför standardtopologiinläsaren topologin. Du kan också ändra den slutförda topologin innan du skickar tillbaka den till mediesessionen.

Följande kod visar den allmänna beskrivningen av den här metoden. Den visar ingen information om metoden Load eftersom dessa beror på programmets särskilda krav.

class CTopoLoader : public IMFTopoLoader
{
public:

    static HRESULT CreateInstance(REFIID iid, void **ppv)
    {
        HRESULT hr = S_OK;

        CTopoLoader *pTopoLoader = new (std::nothrow) CTopoLoader(&hr);
        
        if (pTopoLoader == NULL)
        {
            return E_OUTOFMEMORY;
        }

        if (SUCCEEDED(hr))
        {
            hr = pTopoLoader->QueryInterface(iid, ppv);
        }

        SafeRelease(&pTopoLoader);
        return hr;
    }

    // IUnknown methods.
    STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
    {
        static const QITAB qit[] = 
        {
            QITABENT(CTopoLoader, IMFTopoLoader),
            { 0 },
        };
        return QISearch(this, qit, riid, ppv);
    }

    STDMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&m_cRef);
    }

    STDMETHODIMP_(ULONG) Release()
    {
        long cRef = InterlockedDecrement(&m_cRef);
        if (cRef == 0)
        {
            delete this;
        }
        return cRef;
    }

    // IMTopoLoader methods.
    STDMETHODIMP Load(
        IMFTopology *pInput, 
        IMFTopology **ppOutput, 
        IMFTopology *pCurrent
        )
    {
        HRESULT hr = S_OK;

        // TODO: Add custom topology-building code here.
        //       Modify pInput as needed.

        if (SUCCEEDED(hr))
        {
            hr = m_pTopoLoader->Load(pInput, ppOutput, pCurrent);
        }

        // TODO: Add custom topology-building code here.
        //       Modify ppOutput as needed.

        return hr;
    }

private:
    CTopoLoader(HRESULT *phr) : m_cRef(1), m_pTopoLoader(NULL)
    {
        *phr = MFCreateTopoLoader(&m_pTopoLoader);
    }

    virtual ~CTopoLoader()
    {
        SafeRelease(&m_pTopoLoader);
    }

private:
    long            m_cRef;          // Reference count.
    IMFTopoLoader   *m_pTopoLoader;  // Standard topoloader.
};

MFCreateTopoLoader

Advanced Toppology Building