Bagikan melalui


MFTs asinkron

Topik ini menjelaskan pemrosesan data asinkron untuk transformasi Media Foundation (MFTs).

Nota

Topik ini berlaku untuk Windows 7 atau yang lebih baru.

 

Tentang MFTs Asinkron

Ketika MFTs diperkenalkan di Windows Vista, API dirancang untuk pemrosesan data sinkron. Dalam model itu, MFT selalu menunggu untuk mendapatkan input, atau menunggu untuk menghasilkan output.

Pertimbangkan dekoder video biasa. Untuk mendapatkan bingkai yang didekodekan, klien memanggil IMFTransform::P rocessOutput. Jika dekoder memiliki data yang cukup untuk mendekode bingkai, ProcessOutput memblokir saat MFT mendekode bingkai. Jika tidak, ProcessOutput mengembalikan MF_E_TRANSFORM_NEED_MORE_INPUT, yang menunjukkan bahwa klien harus memanggil IMFTransform::P rocessInput.

Model ini berfungsi dengan baik jika dekoder melakukan semua operasi decoding-nya pada satu utas. Tetapi misalkan dekoder menggunakan beberapa utas untuk mendekode bingkai secara paralel. Untuk performa terbaik, dekoder harus menerima input baru setiap kali utas decoding menjadi menganggur. Tetapi tingkat di mana utas menyelesaikan operasi decoding tidak akan selaras dengan panggilan klien untuk ProcessInput dan ProcessOutput, yang mengakibatkan utas menunggu pekerjaan.

Windows 7 memperkenalkan pemrosesan asinkron berbasis peristiwa, untuk MFTs. Dalam model ini, setiap kali MFT membutuhkan input atau memiliki output, MFT mengirimkan peristiwa ke klien.

Persyaratan Umum

Topik ini menjelaskan bagaimana MFT asinkron berbeda dari MFT sinkron. Kecuali jika dicatat dalam topik ini, dua model pemrosesan sama. (Khususnya, negosiasi format sama.)

MFT asinkron harus menerapkan antarmuka berikut:

Peristiwa

MFT asinkron menggunakan peristiwa berikut untuk memberi sinyal status pemrosesan datanya:

Peristiwa Deskripsi
METransformNeedInput Dikirim ketika MFT dapat menerima lebih banyak input.
METransformHaveOutput Dikirim ketika MFT memiliki output.
METransformDrainComplete Dikirim saat operasi pengurasan selesai. Lihat Pengurasan.
METransformMarker Dikirim saat penanda sedang diproses. Lihat Penanda.

 

Peristiwa ini dikirim di luar band. Penting untuk memahami perbedaan antara peristiwa dalam band dan out-of-band dalam konteks MFT.

Desain MFT asli mendukung peristiwa dalam band. Peristiwa dalam band berisi informasi tentang aliran data, seperti informasi tentang perubahan format. Klien mengirim peristiwa dalam band ke MFT dengan memanggil IMFTransform::P rocessEvent. MFT dapat mengirim peristiwa dalam band kembali ke klien dalam metodeProcessOutput. (Secara khusus, peristiwa disampaikan dalam pEvents anggota struktur MFT_OUTPUT_DATA_BUFFER.)

MFT mengirimkan peristiwa di luar band melalui antarmukaIMFMediaEventGeneratorsebagai berikut:

  1. MFT mengimplementasikan antarmukaIMFMediaEventGenerator, seperti yang dijelaskan dalam Media Event Generators.
  2. Klien memanggil IUnknown::QueryInterface pada MFT untuk antarmukaIMFMediaEventGenerator. MFT asinkron harus mengekspos antarmuka ini. MFTs sinkron tidak boleh mengekspos antarmuka ini.
  3. Klien memanggil IMFMediaEventGenerator::BeginGetEvent dan IMFMediaEventGenerator::EndGetEvent untuk menerima peristiwa di luar band dari MFT.

ProcessInput

MetodeIMFTransform::P rocessInputdimodifikasi sebagai berikut:

  1. Saat streaming dimulai, klien mengirim pesan MFT_MESSAGE_NOTIFY_START_OF_STREAM.
  2. Selama streaming, MFT meminta data dengan mengirim peristiwa METransformNeedInput. Data peristiwa adalah pengidentifikasi aliran.
  3. Untuk setiap peristiwa METransformNeedInput, klien memanggil ProcessInput untuk aliran yang ditentukan.
  4. Di akhir streaming, klien dapat memanggil ProcessMessage dengan pesan MFT_MESSAGE_NOTIFY_END_OF_STREAM.

Catatan implementasi:

ProcessOutput

Metode IMFTransform::P rocessOutput dimodifikasi sebagai berikut:

  1. Setiap kali MFT memiliki output, MFT mengirimkan peristiwa METransformHaveOutput.
  2. Untuk setiap peristiwa METransformHaveOutput, klien memanggil ProcessOutput.

Catatan implementasi:

  • Jika klien memanggilProcessOutputdi lain waktu, metode mengembalikan E_UNEXPECTED.
  • MFT asinkron tidak boleh mengembalikan MF_E_TRANSFORM_NEED_MORE_INPUT dari metodeProcessOutput. Jika MFT memerlukan lebih banyak input, MFT akan mengirim peristiwa METransformNeedInput.

Pengeringan

Menguras MFT menyebabkan MFT menghasilkan output sebanyak mungkin dari data input apa pun yang telah dikirim. Menguras MFT asinkron berfungsi sebagai berikut:

  1. Klien mengirim pesan MFT_MESSAGE_COMMAND_DRAIN.
  2. MFT terus mengirim peristiwa METransformHaveOutput hingga tidak memiliki data lagi untuk diproses. Ini tidak mengirim meTransformNeedInput peristiwa selama waktu ini.
  3. Setelah MFT mengirimkan peristiwa METransformHaveOutput terakhir, MFT mengirimkan peristiwa METransformDrainComplete.

Setelah pengurasan selesai, MFT tidak mengirim peristiwa METransformNeedInput lain hingga menerima pesan MFT_MESSAGE_NOTIFY_START_OF_STREAM dari klien.

Pembilasan

Klien dapat menghapus MFT dengan mengirim pesan MFT_MESSAGE_COMMAND_FLUSH. MFT menghilangkan semua sampel input dan output yang dipegangnya.

MFT tidak mengirim peristiwa METransformNeedInput lain hingga menerima pesan MFT_MESSAGE_NOTIFY_START_OF_STREAM dari klien.

Spidol

Klien dapat menandai titik dalam aliran dengan mengirim pesan MFT_MESSAGE_COMMAND_MARKER. MFT merespons sebagai berikut:

  1. MFT menghasilkan sampel output sebanyak mungkin dari data input yang ada, mengirim peristiwa METransformHaveOutput untuk setiap sampel output.
  2. Setelah semua output dihasilkan, MFT mengirimkan peristiwa METransformMarker. Kejadian ini harus dikirim setelah semua peristiwa METransformHaveOutput.

Misalnya, misalkan dekoder memiliki data input yang cukup untuk menghasilkan empat sampel output. Jika klien mengirim pesan MFT_MESSAGE_COMMAND_MARKER, MFT akan mengantre empat peristiwa METransformHaveOutput (satu per sampel output), diikuti oleh peristiwa METransformMarker.

Pesan penanda mirip dengan pesan pengurasan. Namun, pengosongan dianggap sebagai jeda di aliran, sedangkan penanda tidak. Pengurasan dan penanda memiliki perbedaan berikut.

Pengeringan:

  • Saat menguras, MFT tidak mengirim peristiwa METransformNeedInput.
  • MFT membuang data input apa pun yang tidak dapat digunakan untuk membuat sampel output.
  • Beberapa MFT menghasilkan "ekor" di akhir data. Misalnya, efek audio seperti gaung atau gema menghasilkan data tambahan setelah data input berhenti. MFT yang menghasilkan ekor harus melakukannya di akhir operasi pengurasan.
  • Setelah MFT selesai dikuras, MFT menandai sampel output berikutnya dengan atribut MFSampleExtension_Discontinuity, untuk menunjukkan penghentian dalam aliran.

Penanda:

  • MFT terus mengirim peristiwa METransformNeedInput sebelum mengirim peristiwa penanda.
  • MFT tidak membuang data input apa pun. Jika ada data parsial, data harus diproses setelah titik penanda.
  • MFT tidak menghasilkan ekor pada titik penanda.
  • MFT tidak mengatur bendera penghentian setelah titik penanda.

Format Perubahan

MFT asinkron harus mendukung perubahan format dinamis, seperti yang dijelaskan dalam Menangani Perubahan Aliran.

Atribut

MFT asinkron harus menerapkan metode IMFTransform::GetAttributes untuk mengembalikan penyimpanan atribut yang valid. Atribut berikut berlaku untuk MFTs asinkron:

Atribut Deskripsi
MF_TRANSFORM_ASYNC MFT harus mengatur atribut ini ke TRUE (1). Klien dapat mengkueri atribut ini untuk menemukan apakah MFT tidak sinkron.
MF_TRANSFORM_ASYNC_UNLOCK
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE MFT harus mengatur atribut ini ke TRUE (1). Klien dapat mengasumsikan bahwa atribut ini diatur.

 

Membuka kunci MFT Asinkron

MFTs asinkron tidak kompatibel dengan model pemrosesan data MFT asli. Untuk mencegah MFTs asinkron merusak aplikasi yang ada, mekanisme berikut didefinisikan:

Klien memanggil IMFTransform::GetAttributes di MFT. Klien meminta atribut MF_TRANSFORM_ASYNC ini. Untuk MFT asinkron, nilai atribut ini adalah **TRUE**. Untuk membuka kunci MFT, klien harus mengatur atribut MF_TRANSFORM_ASYNC_UNLOCK ke **TRUE**.

Hingga klien membuka kunci MFT, semua metode IMFTransform harus mengembalikan MF_E_TRANSFORM_ASYNC_LOCKED, dengan pengecualian berikut:

Kode berikut menunjukkan cara membuka kunci MFT asinkron:

HRESULT UnlockAsyncMFT(IMFTransform *pMFT)
{
    IMFAttributes *pAttributes = NULL;

    HRESULT hr = hr = pMFT->GetAttributes(&pAttributes);

    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
        pAttributes->Release();
    }
    
    return hr;
}

Mematikan MFT

MFTs asinkron harus mengimplementasikan antarmukaIMFShutdown.

  • Matikan: MFT harus mematikan antrean peristiwanya. Jika menggunakan antrean peristiwa standar, panggil IMFMediaEventQueue::Shutdown. Secara opsional, MFT dapat merilis sumber daya lain. Klien tidak boleh menggunakan MFT setelah memanggil Matikan.
  • GetShutdownStatus: SetelahMatikandipanggil, MFT harus mengembalikan nilai MFSHUTDOWN_COMPLETED dalam parameter pStatus. Ini tidak boleh mengembalikan nilai MFSHUTDOWN_INITIATED.

Pendaftaran dan Enumerasi

Untuk mendaftarkan MFT asinkron, panggil fungsiMFTRegister dan atur bendera MFT_ENUM_FLAG_ASYNCMFT di parameter Bendera. (Sebelumnya bendera ini dicadangkan.)

Untuk menghitung MFT asinkron, panggil fungsiMFTEnumExdan atur bendera MFT_ENUM_FLAG_ASYNCMFT di parameter Bendera. Untuk kompatibilitas mundur, fungsi MFTEnum tidak menghitung MFT asinkron. Jika tidak, menginstal MFT asinkron di komputer pengguna dapat merusak aplikasi yang ada.

Transformasi Media Foundation