Bagikan melalui


Mode Tanpa Jendela VMR

[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Tangkapan 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 Audio/Video Capture 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.]

Mode tanpa jendela adalah cara yang disukai bagi aplikasi untuk merender video di dalam jendela aplikasi. Dalam mode tanpa jendela, Video Mixing Renderer tidak memuat komponen Window Manager-nya, dan karenanya tidak mendukung antarmuka IBasicVideo atau IVideoWindow . Sebagai gantinya, aplikasi menyediakan jendela pemutaran dan mengatur persegi panjang tujuan di area klien agar VMR menggambar video. VMR menggunakan objek clipper DirectDraw untuk memastikan bahwa video diklip ke jendela aplikasi dan tidak muncul di jendela lain. VMR tidak mensubkelas jendela aplikasi atau menginstal kait sistem/proses apa pun.

Dalam mode tanpa jendela, urutan peristiwa selama koneksi dan transisi ke status eksekusi adalah sebagai berikut:

  • Filter upstram mengusulkan jenis media, yang diterima atau ditolak VMR.
  • Jika jenis media diterima, VMR memanggil penyaji alokator untuk mendapatkan permukaan DirectDraw. Jika permukaan berhasil dibuat, pin tersambung dan VMR siap untuk beralih ke status eksekusi.
  • Saat grafik filter berjalan, dekoder memanggil GetBuffer untuk mendapatkan sampel media dari alokator. VMR meminta penyaji alokator untuk memastikan bahwa kedalaman piksel, ukuran persegi panjang, dan parameter lain pada permukaan DirectDraw-nya kompatibel dengan video masuk. Jika kompatibel, VMR mengembalikan permukaan DirectDraw ke dekoder. Setelah dekoder didekodekan ke permukaan, Unit Sinkronisasi Inti VMR memvalidasi stempel waktu. Unit ini memblokir panggilan Terima hingga waktu presentasi tiba. Pada saat itu, VMR memanggil PresentImage pada penyaji alokator, yang menyajikan permukaan ke kartu grafis.

Ilustrasi berikut menunjukkan VMR dalam mode tanpa jendela dengan beberapa aliran input.

vmr dalam mode tanpa jendela

Mengonfigurasi VMR-7 untuk Mode Tanpa Jendela

Untuk mengonfigurasi VMR-7 untuk mode tanpa jendela, lakukan semua langkah berikut sebelum menyambungkan salah satu pin input VMR:

  1. Buat filter dan tambahkan ke grafik.

  2. Panggil metode IVMRFilterConfig::SetRenderingMode dengan bendera VMRMode_Windowless.

  3. Secara opsional, konfigurasikan VMR untuk beberapa aliran input dengan memanggil IVMRFilterConfig::SetNumberOfStreams. VMR membuat pin input untuk setiap aliran. Gunakan antarmuka IVMRMixerControl untuk mengatur urutan Z dan parameter lain untuk aliran. Untuk informasi selengkapnya, lihat VMR dengan Beberapa Aliran (Mode Pencampuran).

    Jika Anda tidak memanggil SetNumberOfStreams, VMR-7 default ke satu pin input. Setelah pin input tersambung, jumlah pin tidak dapat diubah.

  4. Panggil IVMRWindowlessControl::SetVideoClippingWindow untuk menentukan jendela tempat video yang dirender akan muncul.

Setelah langkah-langkah ini selesai, Anda dapat menyambungkan pin input filter VMR. Ada berbagai cara untuk membangun grafik, seperti menyambungkan pin secara langsung, menggunakan metode Intelligent Connect seperti IGraphBuilder::RenderFile, atau menggunakan metode ICaptureGraphBuilder2::RenderStream Capture Graph Builder. Untuk informasi selengkapnya, lihat Teknik Graph-Building Umum.

Untuk mengatur posisi video dalam jendela aplikasi, panggil metode IVMRWindowlessControl::SetVideoPosition . Metode IVMRWindowlessControl::GetNativeVideoSize mengembalikan ukuran video asli. Selama pemutaran, aplikasi harus memberi tahu VMR tentang pesan Windows berikut:

Catatan

Aplikasi MFC harus menentukan penangan pesan WM_ERASEBKGND kosong, atau area tampilan video tidak akan dicat ulang dengan benar.

 

Mengonfigurasi VMR-9 untuk Mode Tanpa Jendela

Untuk mengonfigurasi VMR-9 untuk mode tanpa jendela, gunakan langkah-langkah yang dijelaskan untuk VMR-7 untuk mode Windowless, tetapi gunakan antarmuka IVMRFilterConfig9 dan IVMRWindowlessControl9 . Satu-satunya perbedaan yang signifikan adalah bahwa VMR-9 membuat empat pin input secara default, bukan satu pin input. Oleh karena itu, Anda hanya perlu memanggil SetNumberOfStreams jika Anda mencampur lebih dari empat aliran video.

Contoh Kode

Kode berikut menunjukkan cara membuat filter VMR-7, menambahkannya ke grafik filter DirectShow, lalu memasukkan VMR ke dalam mode tanpa jendela. Untuk VMR-9, gunakan CLSID_VideoMixingRenderer9 di CoCreateInstance dan antarmuka VMR-9 yang sesuai.

HRESULT InitializeWindowlessVMR(
    HWND hwndApp,         // Application window.
    IFilterGraph* pFG,    // Pointer to the Filter Graph Manager.
    IVMRWindowlessControl** ppWc,  // Receives the interface.
    DWORD dwNumStreams,  // Number of streams to use.
    BOOL fBlendAppImage  // Are we alpha-blending a bitmap?
    )
{
    IBaseFilter* pVmr = NULL;
    IVMRWindowlessControl* pWc = NULL;
    *ppWc = NULL;

    // Create the VMR and add it to the filter graph.
    HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL,
       CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
    if (FAILED(hr))
    {
        return hr;
    }
    hr = pFG->AddFilter(pVmr, L"Video Mixing Renderer");
    if (FAILED(hr))
    {
        pVmr->Release();
        return hr;
    }

    // Set the rendering mode and number of streams.  
    IVMRFilterConfig* pConfig;
    hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
    if (SUCCEEDED(hr)) 
    {
        pConfig->SetRenderingMode(VMRMode_Windowless);

        // Set the VMR-7 to mixing mode if you want more than one video
        // stream, or you want to mix a static bitmap over the video.
        // (The VMR-9 defaults to mixing mode with four inputs.)
        if (dwNumStreams > 1 || fBlendAppImage) 
        {
            pConfig->SetNumberOfStreams(dwNumStreams);
        }
        pConfig->Release();

        hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
        if (SUCCEEDED(hr)) 
        {
            pWc->SetVideoClippingWindow(hwndApp);
            *ppWc = pWc;  // The caller must release this interface.
        }
    }
    pVmr->Release();

    // Now the VMR can be connected to other filters.
    return hr;
}

Menggunakan Mode Tanpa Jendela