Perbandingan MFTs dan DMO

Transformasi Media Foundation (MFTs) adalah evolusi dari model transformasi yang pertama kali diperkenalkan dengan DirectX Media Objects (DMO). Topik ini merangkum cara utama di mana MFTs berbeda dari DMO. Baca topik ini jika Anda sudah terbiasa dengan antarmuka DMO, atau jika Anda ingin mengonversi DMO yang ada menjadi MFT.

Topik ini berisi bagian berikut:

Jumlah Aliran

DMO memiliki sejumlah aliran tetap, sementara MFT dapat mendukung sejumlah aliran dinamis. Klien dapat menambahkan aliran input, dan MFT dapat menambahkan aliran output baru selama pemrosesan. Namun, MFT tidak diperlukan untuk mendukung aliran dinamis. MFT dapat memiliki sejumlah aliran tetap, sama seperti DMO.

Metode berikut digunakan untuk mendukung aliran dinamis pada MFT:

Selain itu, metode IMFTransform::P rocessOutput menentukan perilaku untuk menambahkan atau menghapus aliran output.

Karena DMO memiliki aliran tetap, aliran pada DMO diidentifikasi menggunakan nilai indeks berbasis nol. MFTs, di sisi lain, menggunakan pengidentifikasi aliran yang tidak selalu sesuai dengan nilai indeks. Ini karena jumlah aliran pada MFT mungkin berubah. Misalnya, streaming 0 mungkin dihapus, membiarkan streaming 1 sebagai aliran pertama. Namun, MFT dengan jumlah aliran tetap harus mengamati konvensi yang sama dengan DMO dan menggunakan nilai indeks untuk pengidentifikasi aliran.

Negosiasi Format

MFTs menggunakan antarmuka IMFMediaType untuk menjelaskan jenis media. Jika tidak, format negosiasi dengan MFTs berfungsi pada prinsip-prinsip dasar yang sama seperti dengan DMO. Tabel berikut mencantumkan metode negosiasi format untuk DMO dan metode terkait untuk MFTs.

Metode DMO Metode MFT
IMediaObject::GetInputCurrentType IMFTransform::GetInputCurrentType
IMediaObject::GetInputMaxLatency IMFTransform::GetInputStreamInfo
IMediaObject::GetInputSizeInfo IMFTransform::GetInputStreamInfo
IMediaObject::GetInputType IMFTransform::GetInputAvailableType
IMediaObject::GetOutputCurrentType IMFTransform::GetOutputCurrentType
IMediaObject::GetOutputSizeInfo IMFTransform::GetOutputStreamInfo
IMediaObject::GetOutputType IMFTransform::GetOutputAvailableType

 

Streaming

Seperti DMO, MFO memproses data melalui panggilan ke metode ProcessInput dan ProcessOutput . Berikut adalah perbedaan utama antara proses DMO dan MFT saat streaming data.

Mengalokasikan Sumber Daya

MFTs tidak memiliki metode IMediaObject::AllocateStreamingResources dan IMediaObject::FreeStreamingResources yang digunakan dengan DMO. Untuk menangani alokasi dan dealokasi sumber daya secara efisien, MFT dapat merespons pesan berikut dalam metode IMFTransform::P rocessMessage :

Selain itu, klien dapat memberi sinyal awal dan akhir aliran dengan memanggil ProcessMessage dengan pesan berikut:

Kedua pesan ini tidak memiliki DMO yang sama persis.

Memproses Data

MFTs menggunakan sampel media untuk menyimpan data input dan output. Sampel media mengekspos antarmuka IMFSample , dan berisi data berikut:

  • Stempel waktu dan durasi.
  • Atribut yang berisi informasi per sampel. Untuk daftar atribut, lihat Atribut Sampel.
  • Nol atau lebih buffer media. Setiap buffer media mengekspos antarmuka IMFMediaBuffer .

Antarmuka IMFMediaBuffer mirip dengan antarmuka DMO IMediaBuffer . Untuk mengakses buffer memori yang mendasar, panggil IMFMediaBuffer::Lock. Metode ini kira-kira setara dengan IMediaBuffer::GetBufferAndLength untuk DMO.

Untuk data video yang tidak dikompresi, buffer media mungkin juga mendukung antarmuka IMF2DBuffer . MFT yang memproses video yang tidak dikompresi (baik sebagai input atau output) harus disiapkan untuk menggunakan antarmuka IMF2DBuffer jika buffer mengeksposnya. Untuk informasi selengkapnya, lihat Buffer Video yang Tidak Dikompresi.

Media Foundation menyediakan beberapa implementasi standar IMFMediaBuffer, sehingga umumnya tidak perlu menulis implementasi Anda sendiri. Untuk membuat buffer DMO dari buffer Media Foundation, panggil MFCreateLegacyMediaBufferOnMFMediaBuffer.

Pembilasan

MFTs tidak memiliki metode Flush . Untuk menghapus MFT, panggil IMFTransform::P rocessMessage dengan pesan MFT_MESSAGE_COMMAND_FLUSH .

Penghentian Streaming

MFTs tidak memiliki metode Penghentian . Untuk memberi sinyal penghentian dalam aliran, atur atribut MFSampleExtension_Discontinuity pada sampel input.

Perbedaan Lain-lain

Berikut adalah beberapa perbedaan kecil tambahan antara MFTs dan DMO.

Bendera

Tabel berikut mencantumkan berbagai bendera DMO dan setara MFT-nya. Setiap kali bendera DMO memetakan langsung ke bendera MFT, kedua bendera memiliki nilai numerik yang sama. Namun, beberapa bendera DMO tidak memiliki MFT yang sama persis, dan sebaliknya.

Bendera ProcessInput

DMO: enumerasi _DMO_INPUT_DATA_BUFFER_FLAGS .

MFTs: Tidak ada enumerasi yang setara.

Bendera DMO Bendera MFT
DMO_INPUT_DATA_BUFFERF_SYNCPOINT Tidak ada bendera yang setara. Sebagai gantinya, atur atribut MFSampleExtension_CleanPoint pada sampel.
DMO_INPUT_DATA_BUFFERF_TIME Tidak ada bendera yang setara. Sebagai gantinya, panggil IMFSample::SetSampleTime pada sampel.
DMO_INPUT_DATA_BUFFERF_TIMELENGTH Tidak ada bendera yang setara. Sebagai gantinya, panggil IMFSample::SetSampleDuration pada sampel.

 

Bendera ProcessOutput

DMO: enumerasi _DMO_PROCESS_OUTPUT_FLAGS .

MFTs: enumerasi _MFT_PROCESS_OUTPUT_FLAGS .

Bendera DMO Bendera MFT
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

DMO: enumerasi _DMO_OUTPUT_DATA_BUFFER_FLAGS .

MFTs: enumerasi _MFT_OUTPUT_DATA_BUFFER_FLAGS .

Bendera DMO Bendera MFT
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT Tidak ada bendera yang setara. Sebagai gantinya, periksa atribut MFSampleExtension_CleanPoint pada sampel.
DMO_OUTPUT_DATA_BUFFERF_TIME Tidak ada bendera yang setara. Sebagai gantinya, panggil IMFSample::GetSampleTime pada sampel.
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH Tidak ada bendera yang setara. Sebagai gantinya, panggil IMFSample::GetSampleDuration pada sampel.
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
Tidak ada bendera yang setara. MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
Tidak ada bendera yang setara. MFT_OUTPUT_DATA_BUFFER_STREAM_END
Tidak ada bendera yang setara. MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE

 

Bendera GetInputStatus

DMO: enumerasi _DMO_INPUT_STATUS_FLAGS .

MFTs: enumerasi _MFT_INPUT_STATUS_FLAGS .

Bendera DMO Bendera MFT
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

Bendera GetOutputStatus

DMO: Tidak ada enumerasi yang setara.

MFTs: enumerasi _MFT_OUTPUT_STATUS_FLAGS .

Bendera DMO Bendera MFT
Tidak ada bendera yang setara. MFT_OUTPUT_STATUS_SAMPLE_READY

 

Bendera GetInputStreamInfo

DMO: enumerasi _DMO_INPUT_STREAM_INFO_FLAGS .

MFTs: enumerasi _MFT_INPUT_STREAM_INFO_FLAGS .

Bendera DMO Bendera MFT
DMO_INPUT_STREAMF_WHOLE_SAMPLES MFT_INPUT_STREAM_WHOLE_SAMPLES
DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_INPUT_STREAMF_HOLDS_BUFFERS MFT_INPUT_STREAM_HOLDS_BUFFERS
Tidak ada bendera yang setara. MFT_INPUT_STREAM_DOES_NOT_ADDREF
Tidak ada bendera yang setara. MFT_INPUT_STREAM_REMOVABLE
Tidak ada bendera yang setara. MFT_INPUT_STREAM_OPTIONAL

 

Bendera GetOutputStreamInfo

DMO: enumerasi _DMO_OUTPUT_STREAM_INFO_FLAGS .

MFTs: enumerasi _MFT_OUTPUT_STREAM_INFO_FLAGS .

Bendera DMO Bendera MFT
DMO_OUTPUT_STREAMF_WHOLE_SAMPLES MFT_OUTPUT_STREAM_WHOLE_SAMPLES
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_OUTPUT_STREAMF_DISCARDABLE MFT_OUTPUT_STREAM_DISCARDABLE
DMO_OUTPUT_STREAMF_OPTIONAL MFT_OUTPUT_STREAM_OPTIONAL
Tidak ada bendera yang setara. MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
Tidak ada bendera yang setara. MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
Tidak ada bendera yang setara. MFT_OUTPUT_STREAM_LAZY_READ
Tidak ada bendera yang setara. MFT_OUTPUT_STREAM_REMOVABLE

 

Bendera SetInputType/SetOutputType

DMO: enumerasi _DMO_SET_TYPE_FLAGS .

MFTs: enumerasi _MFT_SET_TYPE_FLAGS .

Bendera DMO Bendera MFT
DMO_SET_TYPEF_TEST_ONLY MFT_SET_TYPE_TEST_ONLY
DMO_SET_TYPEF_CLEAR Tidak ada bendera yang setara. Sebagai gantinya, atur jenis media ke NULL untuk menghapus jenis media.

 

Kode Kesalahan

Tabel berikut menunjukkan cara memetakan kode kesalahan DMO ke kode kesalahan MFT. Objek MFT/DMO hibrid harus mengembalikan kode kesalahan DMO dari metode IMediaObject dan kode kesalahan MFT dari metode IMFTransform . Kode kesalahan DMO ditentukan dalam file header MediaErr.h. Kode kesalahan MFT ditentukan dalam file header mferror.h.

Kode kesalahan DMO Kode kesalahan MFT
DMO_E_INVALIDTYPE MF_E_INVALIDTYPE
DMO_E_INVALIDSTREAMINDEX MF_E_INVALIDSTREAMNUMBER
DMO_E_NOTACCEPTING MF_E_NOTACCEPTING
DMO_E_NO_MORE_ITEMS MF_E_NO_MORE_TYPES
DMO_E_TYPE_NOT_ACCEPTED MF_E_INVALIDMEDIATYPE
DMO_E_TYPE_NOT_SET MF_E_TRANSFORM_TYPE_NOT_SET

 

Membuat Objek DMO/MFT Hibrid

Antarmuka IMFTransform secara longgar didasarkan pada IMediaObject, yang merupakan antarmuka utama untuk DirectX Media Objects (DMO). Dimungkinkan untuk membuat objek yang mengekspos kedua antarmuka. Namun, ini dapat menyebabkan penamaan tabrakan, karena antarmuka memiliki beberapa metode yang memiliki nama yang sama. Anda dapat menyelesaikan masalah ini dengan salah satu dari dua cara:

Solusi 1: Sertakan baris berikut di bagian atas file .cpp apa pun yang berisi fungsi MFT:

#define MFT_UNIQUE_METHOD_NAMES

Ini mengubah deklarasi antarmuka IMFTransform sehingga sebagian besar nama metode diawali dengan "MFT". Dengan demikian, IMFTransform::P rocessInput menjadi IMFTransform::MFTProcessInput, sementara IMediaObject::P rocessInput mempertahankan nama aslinya. Teknik ini paling berguna jika Anda mengonversi DMO yang ada menjadi DMO/MFT hibrid. Anda dapat menambahkan metode MFT baru tanpa mengubah metode DMO.

Solusi 2: Gunakan sintaks C++ untuk membedakan nama yang diwarisi dari lebih dari satu antarmuka. Misalnya, deklarasikan versi MFT ProcessInput sebagai berikut:

CMyHybridObject::IMFTransform::ProcessInput(...)

Deklarasikan versi DMO ProcessInput seperti ini:

CMyHybridObject::IMediaObject::ProcessInput(...)

Jika Anda melakukan panggilan internal ke metode dalam objek, Anda dapat menggunakan sintaks ini, tetapi melakukannya akan mengambil alih status virtual metode. Cara yang lebih baik untuk melakukan panggilan dari dalam objek adalah sebagai berikut:

hr = ((IMediaObject*)this)->ProcessInput(...)

Dengan begitu, jika Anda memperoleh kelas lain dari CMyHybridObject dan mengambil alih metode CMyHybridObject::IMediaObject::P rocessInput, metode virtual yang benar dipanggil. Antarmuka DMO di dokumentasikan dalam dokumentasi DirectShow SDK.

Transformasi Media Foundation