MFTs asinkron

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

Catatan

Topik ini berlaku untuk Windows 7 atau yang lebih baru.

 

Tentang MFTs Asinkron

Ketika MFT 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, menunjukkan bahwa klien harus memanggil IMFTransform::P rocessInput.

Model ini bekerja dengan baik jika dekoder melakukan semua operasi pendekodeannya 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 ke ProcessInput dan ProcessOutput, yang mengakibatkan utas menunggu pekerjaan.

Windows 7 memperkenalkan pemrosesan asinkron berbasis peristiwa untuk MFT. 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, kedua model pemrosesan sama. (Khususnya, negosiasi format sama.)

MFT asinkron harus mengimplementasikan antarmuka berikut:

Acara

MFT asinkron menggunakan peristiwa berikut untuk menandakan status pemrosesan datanya:

Kejadian Deskripsi
METransformNeedInput Dikirim ketika MFT dapat menerima lebih banyak input.
METransformHaveOutput Dikirim ketika MFT memiliki output.
METransformDrainComplete Dikirim ketika 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 in-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 metode ProcessOutput . (Secara khusus, peristiwa disampaikan dalam anggota pEvents dari struktur MFT_OUTPUT_DATA_BUFFER .)

MFT mengirimkan peristiwa out-of-band melalui antarmuka IMFMediaEventGenerator sebagai berikut:

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

ProcessInput

Metode IMFTransform::P rocessInput dimodifikasi 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 memanggil ProcessOutput di lain waktu, metode akan mengembalikan E_UNEXPECTED.
  • MFT asinkron tidak boleh mengembalikan MF_E_TRANSFORM_NEED_MORE_INPUT dari metode ProcessOutput . Jika MFT memerlukan lebih banyak input, MFT akan mengirimkan peristiwa METransformNeedInput .

Pengurasan

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

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

Setelah pengurasan selesai, MFT tidak mengirim peristiwa METransformNeedInput lain sampai 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 sampai menerima pesan MFT_MESSAGE_NOTIFY_START_OF_STREAM dari klien.

Penanda

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 dalam 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 menguras, 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 sebagian data, 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 MFTs Asinkron

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

Klien memanggil IMFTransform::GetAttributes pada MFT. Klien meminta untuk 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

MFT asinkron harus mengimplementasikan antarmuka IMFShutdown .

  • 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: Setelah Shutdown dipanggil, MFT harus mengembalikan nilai yang MFSHUTDOWN_COMPLETED dalam parameter pStatus . Ini tidak boleh mengembalikan nilai MFSHUTDOWN_INITIATED.

Pendaftaran dan Enumerasi

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

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

Transformasi Media Foundation