Bagikan melalui


Menyediakan Alokator Kustom

[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Pengambilan Audio/Video di Media Foundation. Fitur-fitur tersebut telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer, IMFMediaEngine , dan Pengambilan Audio/Video di Media Foundation alih-alih DirectShow, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]

Bagian ini menjelaskan cara menyediakan alokator kustom untuk filter. Hanya koneksi IMemInputPin yang dijelaskan, tetapi langkah-langkah untuk koneksi IAsyncReader serupa.

Pertama, tentukan kelas C++ untuk alokator. Alokator Anda dapat berasal dari salah satu kelas alokator standar, CBaseAllocator atau CMemAllocator, atau Anda dapat membuat kelas alokator yang sama sekali baru. Jika Anda membuat kelas baru, kelas tersebut harus mengekspos antarmuka IMemAllocator .

Langkah-langkah yang tersisa bergantung pada apakah alokator Anda termasuk dalam pin input atau pin output pada filter Anda. Pin input memainkan peran yang berbeda dari pin output selama fase negosiasi alokator, karena pin output pada akhirnya memilih alokator.

Menyediakan Alokator Kustom untuk Pin Input

Untuk menyediakan alokator untuk pin input, ganti metode CBaseInputPin::GetAllocator pin input. Dalam metode ini, periksa variabel anggota m_pAllocator . Jika variabel ini non-NULL, itu berarti alokator telah dipilih untuk koneksi ini, sehingga metode GetAllocator harus mengembalikan pointer ke alokator tersebut. Jika m_pAllocatorNULL, itu berarti alokator belum dipilih, sehingga metode GetAllocator harus mengembalikan penunjuk ke alokator pilihan pin input. Dalam hal ini, buat instans alokator kustom Anda dan kembalikan penunjuk IMemAllocator-nya . Kode berikut menunjukkan cara menerapkan metode 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);
}

Saat filter upstram memilih alokator, filter memanggil metode IMemInputPin::NotifyAllocator pin input. Ambil alih metode CBaseInputPin::NotifyAllocator untuk memeriksa properti alokator. Dalam beberapa kasus, pin input mungkin menolak alokator jika bukan alokator kustom Anda, meskipun ini dapat menyebabkan seluruh koneksi pin gagal.

Menyediakan Alokator Kustom untuk Pin Output

Untuk menyediakan alokator untuk pin output, ganti metode CBaseOutputPin::InitAllocator untuk membuat instans alokator Anda:

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

Secara default, kelas CBaseOutputPin meminta alokator dari pin input terlebih dahulu. Jika alokator tersebut tidak cocok, pin output akan membuat alokatornya sendiri. Untuk memaksa koneksi menggunakan alokator kustom Anda, ganti metode CBaseOutputPin::D ecideAllocator . Namun, ketahuilah bahwa ini dapat mencegah pin output Anda terhubung dengan filter tertentu, karena filter lain mungkin juga memerlukan alokator kustomnya sendiri. Opsi ketiga adalah mengalihkan pesanan: Coba alokator kustom Anda terlebih dahulu, lalu kembali ke alokator filter lainnya.

Negosiasi Alokator