Bagikan melalui


Pemuat Topologi Kustom

Ketika aplikasi mengantrekan topologi parsial pada Sesi Media, Sesi Media menggunakan pemuat topologi untuk menyelesaikan topologi. Secara default, Sesi Media menggunakan implementasi Media Foundation standar dari pemuat topologi, tetapi Anda juga dapat memberikan implementasi kustom. Ini memberi Anda lebih banyak kontrol atas topologi akhir. Pemuat topologi kustom harus mengimplementasikan antarmuka IMFTopoLoader .

Untuk mengatur pemuat topologi kustom pada Sesi Media, lakukan hal berikut:

  1. Buat penyimpanan atribut kosong dengan memanggil MFCreateAttributes.
  2. Atur atribut MF_SESSION_TOPOLOADER di penyimpanan atribut. Nilai atribut adalah CLSID dari loader kustom Anda.
  3. Panggil MFCreateMediaSession untuk membuat Sesi Media untuk konten yang tidak terlindungi, atau MFCreatePMPMediaSession untuk membuat Sesi Media di dalam jalur media yang dilindungi (PMP).

Catatan

Untuk menggunakan pemuat topologi kustom di dalam PMP, pemuat topologi harus menjadi komponen tepercaya. Untuk informasi selengkapnya, lihat Jalur Media Terproteksi.

 

Kode berikut menunjukkan cara mengatur pemuat topologi kustom pada Sesi Media.

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

Tidak perlu mengimplementasikan seluruh algoritma pemuatan topologi di pemuat topologi Anda. Sebagai alternatif, Anda dapat membungkus pemuat topologi Media Foundation standar. Dalam implementasi metode IMFTopoLoader::Load Anda, ubah topologi sesuai kebutuhan dan teruskan topologi yang dimodifikasi ke pemuat topologi standar. Kemudian pemuat topologi standar menyelesaikan topologi. Anda juga dapat memodifikasi topologi yang telah selesai sebelum meneruskannya kembali ke Sesi Media.

Kode berikut menunjukkan kerangka umum pendekatan ini. Ini tidak menunjukkan detail metode Muat , karena ini akan tergantung pada persyaratan tertentu dari aplikasi Anda.

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

Bangunan Topologi Tingkat Lanjut