Bagikan melalui


Menggunakan Templat Kelas DMO

[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.]

DirectShow menyertakan templat kelas, IMediaObjectImpl, untuk menerapkan DMO. Templat menangani banyak tugas "pembukuan", seperti memvalidasi parameter input. Dengan menggunakan templat, Anda dapat fokus pada fungsionalitas yang khusus untuk DMO Anda. Selain itu, templat membantu memastikan bahwa Anda membuat implementasi yang kuat. Templat didefinisikan dalam file header Dmoimpl.h, yang terletak di direktori Sertakan SDK.

Templat IMediaObjectImpl mewarisi antarmuka IMediaObject . Untuk membuat DMO menggunakan templat, tentukan kelas baru yang berasal dari IMediaObjectImpl. Templat mengimplementasikan semua metode IMediaObject . Dalam kebanyakan kasus, templat memanggil metode privat yang sesuai pada kelas turunan. Templat menyediakan fitur berikut:

  • Pemeriksaan parameter dasar. Metode templat memverifikasi bahwa parameter yang diperlukan bukan NULL, bahwa indeks aliran berada dalam rentang, dan bahwa bendera valid.
  • Penguncian. Metode templat memanggil dua metode internal, Kunci dan Buka Kunci, untuk menserialisasikan operasi pada DMO. Fitur ini memastikan bahwa DMO aman untuk utas.
  • Jenis media. Templat menyimpan jenis media yang ditetapkan oleh klien, dan menyediakan metode pengaktor untuk jenis media.
  • Streaming. Templat mencegah streaming hingga klien telah mengatur jenis media untuk semua aliran non-opsional. Ini juga memastikan bahwa metode IMediaObject::AllocateStreamingResources dipanggil sebelum streaming dimulai, yang menjamin bahwa sumber daya dialokasikan.

Kelas turunan harus mengimplementasikan antarmuka IUnknown ; templat tidak menyediakan antarmuka ini. Anda dapat menggunakan Active Template Library (ATL) untuk mengimplementasikan IUnknown, atau Anda dapat memberikan beberapa implementasi lainnya. Templat juga tidak menerapkan mekanisme penguncian. Kelas turunan harus mengimplementasikan metode Kunci dan Buka Kunci . Jika Anda membuat kelas menggunakan ATL, Anda dapat menggunakan implementasi ATL default.

Mendeklarasikan Kelas Turunan

Templat kelas IMediaObjectImpl dinyatakan sebagai berikut:

template <class _DERIVED_, int NUMBEROFINPUTS, int NUMBEROFOUTPUTS>
class IMediaObjectImpl : public ImediaObject

Tiga parameter templat adalah _DERIVED_, NUMBEROFINPUTS, dan NUMBEROFOUTPUTS. Atur _DERIVED_ sama dengan nama kelas Anda. Dua parameter lainnya menentukan jumlah aliran input dan aliran output pada DMO. Misalnya, untuk membuat kelas DMO bernama CMyDmo yang mendukung satu aliran input dan dua aliran output, gunakan deklarasi berikut:

class CMyDmo : public IMediaObjectImpl<CMyDmo, 1, 2>

Sisa bagian ini menjelaskan bagaimana templat mengimplementasikan berbagai metode di IMediaObject.

Metode untuk Mengatur Jenis Media

Metode berikut mengatur atau mengambil jenis media pada DMO:

  • GetInputType, GetOutputType. Metode ini mengembalikan jenis media pilihan, berdasarkan nomor aliran dan indeks jenis. Templat memanggil InternalGetInputType atau InternalGetOutputType pada kelas turunan.
  • SetInputType, SetOutputType. Metode ini mengatur jenis media pada aliran, menguji jenis media, atau menghapus jenis media. Untuk memvalidasi jenis media, templat memanggil InternalCheckInputType atau InternalCheckOutputType pada kelas turunan. Kelas turunan mengembalikan S_OK untuk menerima jenis atau DMO_E_INVALIDTYPE untuk menolak jenis. Templat menangani pengaturan atau menghapus jenis media.
  • GetInputCurrentType, GetOutputCurrentType. Metode ini mengembalikan jenis media saat ini untuk aliran, atau DMO_E_TYPE_NOT_SET jika tidak ada jenis yang diatur. Templat sepenuhnya mengimplementasikan metode ini.

Metode Informasi

Metode berikut memberikan informasi tentang DMO.

  • GetInputMaxLatency, SetInputMaxLatency. Metode ini mengambil atau mengatur latensi maksimum. Templat memanggil InternalGetInputMaxLatency atau InternalSetInputMaxLatency pada kelas turunan.
  • GetInputSizeInfo, GetOutputSizeInfo. Metode ini mengembalikan persyaratan buffer DMO untuk aliran tertentu. Jika tidak ada jenis media yang diatur pada aliran tersebut, templat akan mengembalikan DMO_E_TYPE_NOT_SET. Jika tidak, ini memanggil InternalGetInputSizeInfo atau InternalGetOutputSizeInfo pada kelas turunan.
  • GetInputStreamInfo, GetOutputStreamInfo. Metode ini mengembalikan berbagai bendera yang menunjukkan bagaimana klien harus memformat data. Templat memanggil InternalGetInputStreamInfo atau InternalGetOutputStreamInfo pada kelas turunan.
  • GetStreamCount. Metode ini mengembalikan jumlah aliran input dan output. Templat mengimplementasikan metode ini, menggunakan parameter templat.

Metode untuk Alokasi Sumber Daya

  • Metode AllocateStreamingResources mengalokasikan sumber daya apa pun yang dibutuhkan DMO sebelum streaming dimulai. Metode FreeStreamingResources merilis sumber daya yang sama. Templat ini masing-masing memanggil InternalAllocateStreamingResources dan InternalFreeStreamingResources.

Klien DMO tidak diperlukan untuk memanggil metode ini, tetapi templat secara otomatis memanggil AllocateStreamingResources sebelum streaming dimulai. Oleh karena itu, DMO dapat mengasumsikan bahwa sumber daya telah dialokasikan dengan benar pada saat ProcessInput dipanggil. DMO harus memanggil FreeStreamingResources dalam destruktornya.

Selain itu, ketika templat memanggil InternalAllocateStreamingResources, templat menetapkan bendera internal, sehingga tidak memanggil metode itu lagi hingga memanggil InternalFreeStreamingResources. Ini memastikan bahwa sumber daya tidak dialokasikan ulang secara tidak sengaja, yang dapat menyebabkan kebocoran memori.

Metode untuk Streaming

Metode berikut digunakan untuk mengalirkan data:

  • GetInputStatus. Metode ini menunjukkan apakah DMO dapat menerima input saat ini. Templat memanggil InternalAcceptingInput pada kelas turunan. Jika DMO dapat menerima input, kelas turunan mengembalikan S_OK dan templat mengatur bit DMO_INPUT_STATUSF_ACCEPT_DATA dalam parameter dwFlags . Jika tidak, kelas turunan mengembalikan S_FALSE dan templat menetapkan dwFlags ke nol.
  • ProcessInput. Metode ini memproses buffer input. Templat memanggil AllocateStreamingResources, yang dijelaskan sebelumnya. Kemudian memanggil InternalAcceptingInput pada kelas turunan. Jika DMO dapat menerima input baru, templat akan memanggil InternalProcessInput.
  • ProcessOutput. Metode ini memproses serangkaian buffer output, satu buffer untuk setiap aliran output. Templat memanggil AllocateStreamingResources lalu InternalProcessOutput.
  • Penghentian. Metode ini menandakan penghentian dalam aliran input. Templat memanggil InternalAcceptingInput pada kelas turunan. Jika metode tersebut mengembalikan S_OK, templat memanggil InternalDiscontinuity pada kelas turunan.
  • Siram. Metode ini menghapus DMO. Templat memanggil InternalFlush pada kelas turunan. DMO harus membuang buffer input apa pun yang masih harus diproses.

Templat tidak menyediakan dukungan langsung untuk antarmuka IMediaObjectInPlace .

Metode untuk Penguncian

Penguncian digunakan untuk melindungi status DMO di lingkungan multithreaded. Dalam proyek ATL, metode IMediaObject::Lock menyebabkan konflik nama dengan metode KUNCI ATL. Untuk mengatasi konflik, templat mengganti nama metode IMediaObject menjadi DMOLock. Saat Anda mengkompilasi kelas turunan, tentukan FIX_LOCK_NAME sebelum menyertakan file header Dmo.h:

#define FIX_LOCK_NAME
#include <dmo.h>

Direktif ini menyebabkan pra-prosesor menggantikan DMOLock untuk Kunci dalam deklarasi antarmuka IMediaObject . Aplikasi masih dapat memanggil metode menggunakan nama Kunci, karena urutan vtable tidak berubah. Metode DMOLock memanggil Kunci atau Buka Kunci pada kelas turunan. Jika Anda menggunakan ATL untuk mengimplementasikan kelas turunan, metode ini sudah ditentukan oleh ATL, sehingga tidak ada kode tambahan yang diperlukan. Jika Anda tidak menggunakan ATL, Anda harus menyediakan metode Kunci dan Buka Kunci di kelas turunan Anda.

Templat secara otomatis mengunci DMO di setiap metode IMediaObject . Kelas turunan mungkin perlu mengunci DMO di dalam metode publik lain yang diterapkannya (misalnya, jika mendukung IMediaObjectInPlace). Templat kelas juga menyediakan kelas pembantu internal, IMediaObjectImpl::LockIt, yang berguna untuk mengunci dan membuka kunci DMO.

Ringkasan

Untuk metode IMediaObject berikut, templat memanggil metode yang sesuai dengan tanda tangan yang sama pada kelas turunan. Kelas turunan harus mengimplementasikan masing-masing metode yang ditunjukkan di kolom kedua.

Metode IMediaObject Metode Kelas Turunan
AllocateStreamingResources InternalAllocateStreamingResources
Penghentian InternalDiscontinuity
Flush InternalFlush
FreeStreamingResources InternalFreeStreamingResources
GetInputMaxLatency InternalGetInputMaxLatency
GetInputSizeInfo InternalGetInputSizeInfo
GetInputStreamInfo InternalGetInputStreamInfo
GetInputType InternalGetInputType
GetOutputSizeInfo InternalGetOutputSizeInfo
GetOutputStreamInfo InternalGetOutputStreamInfo
GetOutputType InternalGetOutputType
ProcessInput InternalProcessInput
ProcessOutput InternalProcessOutput
SetInputMaxLatency InternalSetInputMaxLatency

 

Untuk metode IMediaObject yang tersisa, tidak ada korespondensi satu-ke-satu antara metode templat dan metode kelas turunan. Tabel berikut ini meringkas metode mana yang sepenuhnya diimplementasikan oleh templat, dan metode mana yang memanggil metode lain pada kelas turunan.

Metode IMediaObject Metode Kelas Turunan
GetInputCurrentType Diimplementasikan sepenuhnya
GetOutputCurrentType Diimplementasikan sepenuhnya
GetStreamCount Diimplementasikan sepenuhnya
GetInputStatus InternalAcceptingInput
Kunci (diimplementasikan sebagai DMOLock) Kunci, Buka Kunci
SetInputType InternalCheckInputType
SetOutputType InternalCheckOutputType

 

Templat Kelas IMediaObjectImpl

Menulis DMO