Model Pemrosesan MFT Dasar

Topik ini menjelaskan bagaimana klien menggunakan transformasi Media Foundation (MFT) untuk memproses data. klien adalah segala sesuatu yang secara langsung memanggil metode pada MFT. Ini mungkin aplikasi atau jalur Media Foundation.

Baca topik ini jika Anda:

  • Menulis aplikasi yang melakukan panggilan langsung ke satu atau beberapa MFTs.
  • Sedang menulis MFT kustom dan ingin memahami perilaku yang diharapkan dari MFT.

Topik ini menjelaskan model pemrosesan sinkron. Dalam model ini, semua metode pemrosesan data memblokir hingga selesai. MFTs juga dapat mendukung model asinkron, yang dijelaskan dalam topik MFTs Asinkron.

Model Pemrosesan Dasar

Membuat MFT

Ada beberapa cara untuk membuat MFT:

  • Panggil fungsi MFTEnum.
  • Panggil fungsiMFTEnumEx.
  • Jika Anda sudah tahu CLSID MFT, cukup panggil CoCreateInstance.

Beberapa MFTs mungkin menyediakan opsi lain, seperti fungsi pembuatan khusus.

Mendapatkan Pengidentifikasi Aliran

MFT memiliki satu atau beberapa aliran . Aliran input menerima data input, dan aliran output menghasilkan data output. Aliran tidak direpresentasikan sebagai objek yang berbeda. Sebagai gantinya, berbagai metode MFT mengambil pengidentifikasi aliran sebagai parameter.

Beberapa MFTs memungkinkan klien untuk menambahkan atau menghapus aliran input. Selama streaming, MFT dapat menambahkan atau menghapus aliran output. (Klien tidak dapat menambahkan atau menghapus aliran output.)

  1. (Opsional.) Panggil IMFTransform::GetStreamLimits untuk mendapatkan jumlah aliran minimum dan maksimum yang dapat didukung MFT. Jika minimum dan maksimum sama, MFT memiliki jumlah aliran tetap.
  2. Panggil IMFTransform::GetStreamCount untuk mendapatkan jumlah awal aliran.
  3. Panggil IMFTransform::GetStreamIDs untuk mendapatkan pengidentifikasi aliran. Jika metode ini mengembalikan E_NOTIMPL, itu berarti MFT memiliki jumlah aliran tetap, dan pengidentifikasi aliran berturut-turut mulai dari nol.
  4. (Opsional.) Jika MFT tidak memiliki jumlah aliran tetap, panggil IMFTransform::AddInputStreams untuk menambahkan lebih banyak aliran input, atau IMFTransform::D eleteInputStream untuk menghapus aliran input. (Anda tidak dapat menambahkan atau menghapus aliran output.)

Atur Tipe Media

Sebelum MFT dapat memproses data, klien harus mengatur jenis media untuk setiap aliran MFT. MFT mungkin mengharuskan klien mengatur jenis input sebelum mengatur jenis output, atau mungkin memerlukan urutan yang berlawanan (jenis output terlebih dahulu). Beberapa MFTs tidak memiliki persyaratan pada pesanan.

MFT dapat menyediakan daftar jenis media pilihan untuk aliran. Selain itu, MFTs dapat menunjukkan format umum yang didukungnya dengan menambahkan informasi ini ke registri.

Untuk mengatur jenis media, lakukan hal berikut:

  1. (Opsional.) Untuk setiap aliran input, panggil IMFTransform::GetInputAvailableType untuk mendapatkan daftar jenis pilihan untuk aliran tersebut.
    • Jika metode ini mengembalikan MF_E_TRANSFORM_TYPE_NOT_SET, Anda harus mengatur jenis output terlebih dahulu; lewati ke langkah 3.
    • Jika metode mengembalikan E_NOTIMPL, MFT tidak memiliki daftar jenis input pilihan; lewati ke langkah 2.
  2. Untuk setiap aliran input, panggil IMFTransform::SetInputType untuk mengatur jenis input. Anda dapat menggunakan jenis media dari langkah 1, atau jenis yang menjelaskan data input Anda. Jika ada aliran yang mengembalikan MF_E_TRANSFORM_TYPE_NOT_SET, lewati ke langkah 3.
  3. (Opsional.) Untuk setiap aliran output, panggil IMFTransform::GetOutputAvailableType untuk mendapatkan daftar jenis pilihan untuk aliran tersebut.
    • Jika metode ini mengembalikan MF_E_TRANSFORM_TYPE_NOT_SET, Anda harus mengatur jenis input terlebih dahulu; kembali ke langkah 1.
    • Jika ada aliran yang mengembalikan E_NOTIMPL, MFT tidak memiliki daftar jenis output pilihan; lewati ke langkah 4.
  4. Untuk setiap aliran output, panggil IMFTransform::SetOutputType untuk mengatur jenis output. Anda dapat menggunakan jenis media dari langkah 3, atau jenis yang menjelaskan format output yang diperlukan.
  5. Jika ada aliran input yang tidak memiliki jenis media, kembali ke langkah 1.

Dapatkan Persyaratan Buffer

Setelah klien mengatur jenis media, klien harus mendapatkan persyaratan buffer untuk setiap aliran:

Memproses Data

MFT dirancang untuk menjadi mesin keadaan yang dapat diandalkan. Tidak melakukan panggilan kembali ke klien.

  1. Panggil IMFTransform::ProcessMessage dengan pesan MFT_MESSAGE_NOTIFY_BEGIN_STREAMING. Pesan ini meminta MFT untuk mengalokasikan sumber daya apa pun yang dibutuhkan selama streaming.
  2. Panggil IMFTransform::P rocessInput pada setidaknya satu aliran input untuk mengirimkan sampel input ke MFT.
  3. (Opsional.) Panggil IMFTransform::GetOutputStatus untuk mengkueri apakah MFT dapat menghasilkan sampel output. Jika metode mengembalikan S_OK, periksa parameter pdwFlags. Jika pdwFlags berisi bendera MFT_OUTPUT_STATUS_SAMPLE_READY, lanjut ke langkah 4. Jika pdwFlags nol, kembali ke langkah 2. Jika metode mengembalikan E_NOTIMPL, buka langkah 4.
  4. Panggil IMFTransform::P rocessOutput untuk mendapatkan data output.
    • Jika metode mengembalikan MF_E_TRANSFORM_NEED_MORE_INPUT, itu berarti MFT memerlukan lebih banyak data input; kembali ke langkah 2.
    • Jika metode mengembalikan MF_E_TRANSFORM_STREAM_CHANGE, itu berarti jumlah aliran output telah berubah, atau format output telah berubah. Klien mungkin perlu mengkueri pengidentifikasi aliran baru atau mengatur jenis media baru. Untuk informasi selengkapnya, lihat dokumentasi untuk ProcessOutput.
  5. Jika masih ada data input yang akan diproses, buka langkah 2. Jika MFT telah menggunakan semua data input yang tersedia, lanjutkan ke langkah 6.
  6. Panggil ProcessMessage dengan pesan MFT_MESSAGE_NOTIFY_END_OF_STREAM.
  7. Panggil ProcessMessage dengan pesan MFT_MESSAGE_COMMAND_DRAIN.
  8. PanggilProcessOutputuntuk mendapatkan output yang tersisa. Ulangi langkah ini hingga metode mengembalikan MF_E_TRANSFORM_NEED_MORE_INPUT. Nilai pengembalian ini menandakan bahwa semua output telah dikosongkan dari MFT. (Jangan perlakukan ini sebagai kondisi kesalahan.)

Urutan yang dijelaskan di sini menyimpan data sesedikit mungkin dalam MFT. Setelah setiap panggilan keProcessInput , klien mencoba mendapatkan output. Beberapa sampel input mungkin diperlukan untuk menghasilkan satu sampel output, atau satu sampel input mungkin menghasilkan beberapa sampel output. Perilaku optimal untuk klien adalah mengambil sampel output dari MFT sampai MFT memerlukan lebih banyak input.

Namun, MFT harus dapat menangani urutan panggilan metode yang berbeda oleh klien. Misalnya, klien mungkin hanya berpindah-pindah antara panggilan ke ProcessInput dan ProcessOutput. MFT harus membatasi jumlah input yang didapatkannya dengan mengembalikan MF_E_NOTACCEPTING dari ProcessInput setiap kali memiliki beberapa output untuk dihasilkan.

Urutan panggilan metode yang dijelaskan di sini bukan satu-satunya urutan peristiwa yang valid. Misalnya, langkah 3 dan 4 mengasumsikan bahwa klien dimulai dengan jenis input lalu mencoba jenis output. Klien juga dapat membalikkan pesanan ini dan memulai dengan jenis output. Dalam kedua kasus, jika MFT memerlukan urutan yang berlawanan, MFT harus mengembalikan kode kesalahan MF_E_TRANSFORM_TYPE_NOT_SET.

Klien dapat memanggil metode informasi, seperti GetInputCurrentType dan GetOutputStreamInfo, kapan saja selama streaming. Klien juga dapat mencoba mengubah jenis media kapan saja. MFT harus mengembalikan kode kesalahan jika ini bukan operasi yang valid. Singkatnya, MFTs sebaiknya tidak banyak berasumsi tentang urutan operasi, selain apa yang didokumentasikan dalam pemanggilan itu sendiri.

Diagram berikut menunjukkan bagan alur prosedur yang dijelaskan dalam topik ini.

diagram alur yang dimulai dari mendapatkan pengidentifikasi aliran, melalui perulangan yang mengatur jenis input, memperoleh input, dan memproses output

Ekstensi ke Model Dasar

Secara opsional, MFT dapat mendukung beberapa ekstensi ke model streaming dasar.

  • Aliran malas-baca. Jika metode IMFTransform::GetOutputStreamInfo mengembalikan bendera MFT_OUTPUT_STREAM_LAZY_READ untuk aliran output, klien tidak perlu mengumpulkan data dari aliran output tersebut. MFT terus menerima input, dan pada titik tertentu MFT akan membuang data output dari aliran tersebut. Jika semua aliran output memiliki bendera ini, MFT tidak akan pernah gagal menerima input. Contohnya mungkin merupakan transformasi visualisasi, di mana klien mendapatkan output hanya ketika memiliki siklus CPU cadangan untuk menggambar visualisasi.
  • Aliran yang dapat dibuang. Jika metodeGetOutputStreamInfo mengembalikan bendera MFT_OUTPUT_STREAM_DISCARDABLE untuk aliran output, klien dapat meminta MFT untuk membuang output, tetapi MFT tidak akan membuang output apa pun kecuali diminta. Ketika MFT mencapai buffer input maksimumnya, klien harus mengumpulkan beberapa data output atau meminta MFT untuk membuang output.
  • Aliran yang opsional. Jika metodeGetOutputStreamInfo mengembalikan bendera MFT_OUTPUT_STREAM_OPTIONAL untuk aliran output, atau metode IMFTransform::GetInputStreamInfo mengembalikan bendera MFT_INPUT_STREAM_OPTIONAL untuk aliran input, aliran tersebut bersifat opsional. Klien tidak perlu mengatur jenis media pada aliran. Jika klien tidak mengatur jenisnya, aliran tidak dipilih. Aliran output yang tidak dipilih tidak menghasilkan sampel, dan klien tidak menyediakan buffer untuk aliran saat memanggil ProcessOutput. Aliran input yang tidak dipilih tidak menerima data input. MFT dapat menandai semua aliran input dan outputnya sebagai opsional. Namun, diharapkan setidaknya satu input dan satu output harus dipilih agar MFT berfungsi.
  • Pemrosesan asinkron. Model pemrosesan asinkron diperkenalkan di Windows 7. Hal ini dijelaskan dalam topik MFTs Asinkron.

IMF2DBuffer

Jika MFT memproses data video yang tidak dikompresi, MFT harus menggunakan antarmukaIMF2DBuffer untuk memanipulasi buffer sampel. Untuk mendapatkan antarmuka ini, kueri antarmukaIMFMediaBufferpada buffer input atau output apa pun. Tidak menggunakan antarmuka ini ketika tersedia dapat mengakibatkan salinan buffer tambahan. Untuk menggunakan antarmuka ini dengan benar, transform tidak boleh mengunci buffer menggunakan antarmuka IMFMediaBuffer saat IMF2DBuffer tersedia.

Untuk informasi selengkapnya tentang memproses data video, lihat Buffer Video Yang Tidak Dikompresi.

Menyiram MFT

Mengosongkan MFT menyebabkan MFT membuang semua data masukannya. Ini dapat menyebabkan jeda dalam aliran output. Klien biasanya akan menghapus MFT sebelum mencari titik baru dalam aliran input atau beralih ke aliran input baru, ketika klien tidak peduli tentang kehilangan data.

Untuk mengosongkan MFT, panggil IMFTransform::ProcessMessage dengan pesan MFT_MESSAGE_COMMAND_FLUSH.

Proses Menguras MFT

Menguras MFT menyebabkan MFT menghasilkan output sebanyak mungkin dari data input apa pun yang telah dikirim. Jika MFT tidak dapat menghasilkan sampel output lengkap dari input yang tersedia, MFT akan menghilangkan data input. Klien biasanya akan menguras MFT ketika mencapai akhir aliran sumber, atau segera sebelum perubahan format dalam aliran sumber. Untuk menguras MFT, lakukan hal berikut:

  1. Panggil ProcessMessage dengan pesan MFT_MESSAGE_COMMAND_DRAIN. Pesan ini memberi tahu MFT bahwa MFT harus mengirimkan data output sebanyak mungkin dari data input yang telah dikirim.
  2. Panggil ProcessOutput untuk mendapatkan data output, hingga metode mengembalikan MF_E_TRANSFORM_NEED_MORE_INPUT.

Saat MFT sedang dikosongkan, MFT tidak akan menerima input lagi.

Sampel Atribut

Sampel input mungkin memiliki atribut yang harus disalin ke sampel output yang sesuai.

Untuk MFT dengan satu input dan satu output, Anda dapat menggunakan aturan umum berikut:

  • Jika setiap sampel input menghasilkan tepat satu sampel output, Anda dapat membiarkan klien menyalin atribut. Biarkan properti MFPKEY_EXATTRIBUTE_SUPPORTED tidak disetel.
  • Jika tidak ada korespondensi satu-ke-satu antara sampel input dan sampel output, MFT harus menentukan atribut yang benar untuk sampel output. Atur properti MFPKEY_EXATTRIBUTE_SUPPORTED ke VARIANT_TRUE.

Diskontinuitas

Penghentian adalah jeda dalam aliran audio atau video. Ketidaksinambungan dapat disebabkan oleh paket yang terputus pada koneksi jaringan, data file yang rusak, perpindahan dari satu aliran sumber ke aliran lainnya, atau berbagai penyebab lainnya. Penghentian disinyalir dengan mengatur atribut MFSampleExtension_Discontinuity pada sampel pertama setelah penghentian. Tidak dimungkinkan untuk menandakan penghentian di tengah sampel. Oleh karena itu, data tak berkesinambungan harus dikirim dalam sampel terpisah.

Beberapa transformasi, terutama yang menangani data yang tidak dikompresi, seperti efek audio dan video, harus mengabaikan penghentian saat memproses data input. MFTs ini umumnya dirancang untuk menangani data berkelanjutan, dan harus memperlakukan data apa pun yang mereka terima sebagai berkelanjutan, bahkan setelah penghentian.

Jika MFT mengabaikan penghentian pada data input, MFT masih harus mengatur bendera penghentian pada sampel output, jika sampel output memiliki stempel waktu yang sama dengan sampel input. Namun, jika sampel output memiliki stempel waktu yang berbeda, MFT tidak boleh menyebarluaskan ketidakselarasan. (Ini akan terjadi di beberapa resampler audio, misalnya.) Penghentian di tempat yang salah di aliran lebih buruk daripada tidak ada penghentian.

Sebagian besar dekode tidak dapat mengabaikan penghentian, karena penghentian memengaruhi interpretasi sampel berikutnya. Teknologi pengodean apa pun yang menggunakan kompresi antar bingkai, seperti MPEG-2, termasuk dalam kategori ini. Beberapa skema pengodean hanya menggunakan kompresi intra-frame, seperti DV dan MJPEG. Dekoder ini dapat dengan aman mengabaikan diskontinuitas.

Transformasi yang merespons diskontinuitas umumnya harus menghasilkan sebanyak mungkin data sebelum diskontinuitas, dan membuang sisanya. Sampel input dengan bendera penghentian harus diproses seolah-olah itu adalah sampel pertama dalam aliran. (Perilaku ini cocok dengan apa yang ditentukan untuk pesan MFT_MESSAGE_COMMAND_DRAIN.) Namun, detail yang tepat akan bergantung pada format media.

Jika dekoder tidak melakukan apa pun untuk mengurangi penghentian, dekoder harus menyalin bendera penghentian ke data output. Demultiplexers dan MFT lainnya yang berfungsi sepenuhnya dengan data terkompresi harus menyalin diskontinuitas apa pun ke aliran keluar mereka. Jika tidak, komponen hilir mungkin tidak dapat mendekode data terkompresi dengan benar. Secara umum, hampir selalu benar untuk meneruskan diskontinuitas ke hilir, kecuali jika MFT berisi kode eksplisit untuk memuluskan diskontinuitas.

Perubahan Format Dinamis

Format dapat berubah selama streaming. Misalnya, rasio aspek dapat berubah di tengah aliran video.

Untuk detail tentang bagaimana perubahan aliran ditangani oleh MFT, lihat Menangani Perubahan Aliran.

Streaming Peristiwa

Untuk mengirim event ke MFT, panggil IMFTransform::ProcessEvent. Jika metode mengembalikan MF_S_TRANSFORM_DO_NOT_PROPAGATE_EVENT, MFT akan mengembalikan event tersebut kepada pemanggil pada panggilan berikutnya ke ProcessOutput. Jika metode mengembalikan nilai HRESULT lainnya, MFT tidak akan mengembalikan peristiwa ke klien di ProcessOutput. Dalam hal ini, klien bertanggung jawab untuk menyebarluaskan peristiwa ke hilir ke komponen berikutnya dalam alur, jika berlaku. Untuk informasi selengkapnya, lihat IMFTransform::ProcessOutput.

Media Foundation Mengubah