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
- Negosiasi Format
- Streaming
- Perbedaan Lain-lain
- Bendera
- Kode Kesalahan
- Membuat Objek DMO/MFT Hibrid
- Topik terkait
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:
- IMFTransform::AddInputStreams
- IMFTransform::D eleteInputStream
- IMFTransform::GetStreamIDs
- IMFTransform::GetStreamLimits
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.
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.
Tidak ada MFT yang setara untuk metode DMO berikut:
MFTs tidak diperlukan untuk mendukung agregasi.
MFTs mendukung operasi yang disebut pengurasan. Tujuan pengurasan adalah untuk memproses data apa pun yang tetap berada di MF, tanpa memberikan data input lagi ke MFT (misalnya, di akhir aliran). Untuk menguras MFT, panggil IMFTransform::P rocessMessage dengan pesan MFT_MESSAGE_COMMAND_DRAIN . Untuk informasi selengkapnya, lihat Model Pemrosesan MFT Dasar.
MFTs dapat memiliki atribut, termasuk atribut per aliran. Gunakan metode berikut untuk mendapatkan atribut dari MFT:
MFTs dapat memproses peristiwa. Untuk mengirim peristiwa ke MFT, panggil IMFTransform::P rocessEvent. MFT dapat mengirim peristiwa ke klien melalui metode ProcessOutput . Untuk informasi selengkapnya, lihat Model Pemrosesan MFT Dasar.
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.
Topik terkait