Sink Media

Sink media adalah objek alur yang menerima data media. Sink media adalah tujuan untuk satu atau beberapa aliran media. Sink media termasuk dalam dua kategori umum:

  • Perender adalah sink media yang menyajikan data untuk diputar. Perender video yang disempurnakan (EVR) menampilkan bingkai video, dan perender audio memutar aliran audio melalui kartu suara atau perangkat audio lainnya.

  • Sink arsip adalah sink media yang menulis data ke file atau penyimpanan lainnya.

Perbedaan utama di antara mereka adalah bahwa sink arsip tidak mengonsumsi data pada laju pemutaran tetap. Sebaliknya, ia menulis data yang diterimanya secepat mungkin.

Sink media mengekspos antarmuka IMFMediaSink . Setiap sink media berisi satu atau beberapa sink aliran. Setiap sink aliran menerima data dari satu aliran. Stream sink mengekspos antarmuka IMFStreamSink . Biasanya aplikasi tidak membuat sink media secara langsung. Sebaliknya, aplikasi membuat satu atau beberapa objek aktivasi, yang digunakan Sesi Media untuk membuat sink. Semua operasi lain pada sink ditangani oleh Sesi Media, dan aplikasi tidak memanggil metode apa pun di sink media atau sink aliran apa pun. Untuk informasi selengkapnya tentang objek aktivasi, lihat Objek Aktivasi.

Anda harus membaca sisa topik ini jika Anda menulis sink media kustom, atau jika Anda ingin menggunakan sink media secara langsung tanpa Sesi Media.

Streaming Sink

Sink media dapat memiliki sejumlah sink aliran tetap, atau dapat mendukung penambahan dan penghapusan sink aliran. Jika memiliki jumlah sink aliran tetap, metode IMFMediaSink::GetCharacteristics mengembalikan bendera MEDIASINK_FIXED_STREAMS. Jika tidak, Anda dapat menambahkan dan menghapus sink streaming. Untuk menambahkan sink stream baru, panggil IMFMediaSink::AddStreamSink. Untuk menghapus sink aliran, panggil IMFMediaSink::RemoveStreamSink. Bendera MEDIASINK_FIXED_STREAMS menunjukkan bahwa sink media tidak mendukung dua metode ini. (Ini mungkin mendukung beberapa cara lain untuk mengonfigurasi jumlah aliran, misalnya dengan mengatur parameter inisialisasi saat sink dibuat.) Daftar sink aliran diurutkan. Untuk menghitungnya berdasarkan nilai indeks, panggil metode IMFMediaSink::GetStreamSinkByIndex .

Stream sink juga memiliki pengidentifikasi. Pengidentifikasi aliran unik dalam sink media, tetapi tidak harus berturut-turut. Bergantung pada sink media, pengidentifikasi aliran mungkin memiliki beberapa arti yang terkait dengan konten. Misalnya, sink arsip mungkin menulis pengidentifikasi aliran ke header file. Jika tidak, mereka arbitrer. Untuk mendapatkan sink streaming oleh pengidentifikasinya, panggil IMFMediaSink::GetStreamSinkById.

Jam Presentasi

Laju di mana sink media mengonsumsi sampel dikontrol oleh Jam Presentasi. Sesi Media memilih jam presentasi dan mengaturnya di sink media dengan memanggil metode IMFMediaSink::SetPresentationClock sink media. Jam presentasi harus diatur pada sink media sebelum streaming dapat dimulai. Setiap sink media memerlukan jam presentasi untuk dijalankan. Sink media menggunakan jam presentasi untuk dua tujuan:

  • Untuk menerima pemberitahuan saat streaming dimulai atau dihentikan. Sink media menerima pemberitahuan ini melalui antarmuka IMFClockStateSink , yang harus diterapkan oleh semua sink media.

  • Untuk menentukan kapan harus merender sampel. Saat sink media menerima sampel baru, sink tersebut mendapatkan stempel waktu dari sampel dan mencoba merender sampel pada waktu presentasi tersebut.

Jam presentasi memperoleh waktu jamnya dari objek lain yang disebut sumber waktu presentasi. Sumber waktu presentasi mengekspos antarmuka IMFPresentationTimeSource . Beberapa sink media memiliki akses ke jam yang akurat, sehingga mereka mengekspos antarmuka ini. Ini berarti bahwa sink media mungkin menjadwalkan sampel terhadap waktu yang disediakan oleh jamnya sendiri. Namun, sink media tidak dapat mengasumsikan hal ini terjadi. Ini harus selalu menggunakan waktu dari jam presentasi, terlepas dari apakah jam presentasi didorong oleh sink media itu sendiri, atau oleh beberapa jam lainnya.

Jika sink media tidak dapat mencocokkan laju dengan jam selain jamnya sendiri, metode GetCharacteristics mengembalikan bendera MEDIASINK_CANNOT_MATCH_CLOCK. Jika bendera ini ada dan jam presentasi menggunakan sumber waktu presentasi yang berbeda, sink media kemungkinan berkinerja buruk. Misalnya, mungkin terjadi kesalahan selama pemutaran.

Sink tanpa tarif adalah sink media yang mengabaikan stempel waktu pada sampel dan mengonsumsi data segera setelah setiap sampel tiba. Sink media tanpa tarif mengembalikan bendera MEDIASINK_RATELESS dari metode GetCharacteristics . Biasanya bendera ini berlaku untuk sink arsip. Jika setiap sink media dalam alur tidak memiliki tarif, Sesi Media menggunakan jam presentasi tanpa tarif khusus. Jam ini berjalan secepat sink mengonsumsi sampel.

Format Aliran

Sebelum sink media dapat menerima sampel, klien harus mengatur jenis media pada sink aliran. Untuk mengatur jenis media, panggil metode IMFStreamSink::GetMediaTypeHandler stream sink . Metode ini mengembalikan penunjuk ke antarmuka IMFMediaTypeHandler . Gunakan antarmuka ini untuk mendapatkan daftar jenis media pilihan, mendapatkan jenis media saat ini, dan mengatur jenis media.

Untuk mendapatkan daftar jenis media pilihan, panggil IMFMediaTypeHandler::GetMediaTypeByIndex. Jenis yang disukai harus diambil sebagai petunjuk untuk klien. Daftar mungkin tidak lengkap atau menyertakan tipe media parsial. Jenis media parsial adalah jenis yang tidak memiliki semua atribut yang diperlukan untuk menjelaskan format yang valid. Misalnya, jenis video parsial mungkin menentukan ruang warna dan kedalaman bit tetapi bukan lebar atau tinggi gambar. Jenis audio parsial mungkin menentukan format kompresi dan laju sampel tetapi bukan jumlah saluran audio.

Untuk mendapatkan jenis media stream sink saat ini, panggil IMFMediaTypeHandler::GetCurrentMediaType. Saat sink aliran pertama kali dibuat, sink mungkin memiliki jenis media default yang sudah diatur, atau mungkin tidak memiliki jenis media hingga klien menetapkannya.

Untuk mengatur jenis media, panggil IMFMediaTypeHandler::SetCurrentMediaType. Beberapa sink aliran mungkin tidak mendukung perubahan jenis setelah ditetapkan. Oleh karena itu, berguna untuk menguji jenis media sebelum mengaturnya. Untuk menguji apakah sink media akan menerima jenis media, (tanpa mengatur jenisnya), panggil IMFMediaTypeHandler::IsMediaTypeSupported.

Aliran data

Sink media menggunakan model penarikan, yang berarti bahwa aliran sink meminta data sesuai kebutuhan. Klien harus merespons secara tepat waktu untuk menghindari kesalahan.

Beberapa sink media mendukung pra-pendaftaran. Pra-pendaftaran adalah proses pemberian data ke sink media sebelum jam presentasi dimulai. Jika sink media mendukung pra-pendaftaran, sink media mengekspos antarmuka IMFMediaSinkPreroll , dan metode GetCharacteristics mengembalikan bendera MEDIASINK_CAN_PREROLL. Pra-pendaftaran memastikan bahwa sink media siap untuk menyajikan sampel pertama saat jam presentasi dimulai. Disarankan agar klien selalu melakukan pra-pendaftaran jika sink media mendukungnya, karena dapat mencegah kesalahan atau celah selama pemutaran.

Aliran data ke sink media berfungsi sebagai berikut:

  1. Klien mengatur jenis media dan jam presentasi. Sink media mendaftarkan dirinya dengan jam presentasi untuk menerima pemberitahuan tentang perubahan status jam.
  2. Secara opsional, kueri klien untuk IMFMediaSinkPreroll. Jika sink media mengekspos antarmuka ini, klien memanggil IMFMediaSinkPreroll::NotifyPreroll. Jika tidak, klien melompat ke langkah 5.
  3. Setiap sink streaming mengirimkan satu atau beberapa peristiwa MEStreamSinkRequestSample . Menanggapi setiap peristiwa ini, klien mendapatkan sampel data berikutnya untuk aliran tersebut dan memanggil IMFStreamSink::P rocessSample.
  4. Ketika setiap sink streaming menerima data pra-pendaftaran yang cukup, sink akan mengirimkan peristiwa MEStreamSinkPrerolled .
  5. Klien memanggil IMFPresentationClock::Start untuk memulai jam presentasi.
  6. Jam presentasi memberi tahu sink media bahwa jam dimulai, dengan memanggil IMFClockStateSink::OnClockStart.
  7. Untuk mendapatkan lebih banyak data, setiap sink streaming mengirimkan peristiwa MEStreamSinkRequestSample . Menanggapi setiap peristiwa ini, klien mendapatkan sampel berikutnya dan memanggil ProcessSample. Langkah ini diulang hingga presentasi berakhir.

Sebagian besar sink media memproses sampel secara asinkron, sehingga sink aliran dapat mengirimkan lebih dari satu permintaan sampel sekaligus.

Selama streaming, klien dapat memanggil IMFStreamSink::P laceMarker dan IMFStreamSink::Flush kapan saja. Penanda dijelaskan di bagian berikutnya. Pembilasan menyebabkan sink aliran menghilangkan sampel apa pun yang telah diantrekan tetapi belum dirender.

Penanda

Penanda menyediakan cara bagi klien untuk menunjukkan titik tertentu dalam aliran. Penanda terdiri dari informasi berikut:

  • Jenis penanda, didefinisikan sebagai anggota enumerasi MFSTREAMSINK_MARKER_TYPE .
  • Data yang terkait dengan penanda. Arti data tergantung pada jenis penanda. Beberapa jenis penanda tidak memiliki data.
  • Data opsional untuk penggunaan klien sendiri.

Untuk menempatkan penanda, klien memanggil IMFStreamSink::P laceMarker. Sink aliran selesai memproses sampel apa pun yang diterimanya sebelum panggilan PlaceMarker , lalu mengirim peristiwa MEStreamSinkMarker .

Sebagian besar sink media menyimpan antrean sampel yang tertunda, yang mereka proses secara asinkron. Peristiwa penanda harus diserialisasikan dengan pemrosesan sampel, sehingga sink media harus menempatkan penanda dalam antrean yang sama. Misalnya, klien melakukan panggilan metode berikut:

  1. ProcessSample (Sampel #1)
  2. ProcessSample (Sampel #2)
  3. PlaceMarker (Penanda #1)
  4. ProcessSample (Sampel #3)
  5. PlaceMarker (Penanda #2)

Dalam contoh ini, sink aliran harus mengirim peristiwa MEStreamSinkMarker untuk penanda #1 setelah memproses sampel #2, dan peristiwa untuk penanda #2 setelah memproses sampel #3.

Jika klien membersihkan sink aliran, sink aliran segera memproses penanda apa pun yang ada dalam antrean. Ini mengatur kode status ke E_ABORT pada peristiwa ini.

Beberapa penanda berisi informasi yang relevan dengan sink media:

  • MFSTREAMSINK_MARKER_TICK: Menunjukkan ada celah dalam aliran. Sampel berikutnya akan menjadi penghentian.
  • MFSTREAMSINK_MARKER_ENDOFSEGMENT: Menunjukkan akhir segmen atau akhir aliran. Sampel berikutnya (jika ada) mungkin merupakan penghentian.
  • MFSTREAMSINK_MARKER_EVENT: Berisi peristiwa. Tergantung pada jenis peristiwa dan implementasi sink media, sink media mungkin menangani peristiwa atau mengabaikannya.

Perubahan Status

Sink media diberi tahu tentang perubahan status pada jam presentasi melalui antarmuka IMFClockStateSink media sink . Ketika klien mengatur jam presentasi, sink media memanggil IMFPresentationClock::AddClockStateSink untuk mendaftarkan dirinya untuk pemberitahuan dari jam. Tabel berikut ini meringkas bagaimana sink media berprilaku sebagai respons terhadap perubahan status jam.

Perubahan status jam Pemrosesan sampel Pemrosesan penanda
OnClockStart Sampel proses yang stempel waktunya sama dengan atau lebih baru dari waktu mulai jam. Kirim peristiwa MEStreamSinkMarker saat semua sampel diterima sebelum penanda diproses.
OnClockPause Sink media dapat gagal ProcessSample saat dijeda.
Jika sink media menerima sampel saat dijeda, sink media harus mengantrenya hingga jam dimulai ulang. Jangan memproses sampel yang diantrekan saat dijeda.
Jika ada sampel antrean, letakkan penanda ke antrean yang sama. Kirim peristiwa penanda saat jam dimulai ulang.
Jika tidak, kirim peristiwa penanda segera.
OnClockRestart Proses sampel apa pun yang diantrekan saat dijeda, lalu perlakukan sama seperti OnClockStart. Kirim peristiwa MEStreamSinkMarker untuk penanda antrean (diserialisasikan dengan pemrosesan sampel), lalu perlakukan sama seperti OnClockStart.
OnClockStop Hilangkan semua sampel yang diantrekan. Panggilan lebih lanjut ke ProcessSample dapat gagal. Mengirim peristiwa penanda yang diantrekan. Pada panggilan berikutnya ke PlaceMarker, kirim peristiwa penanda segera.

 

Selain itu, stream sink harus mengirim peristiwa berikut ketika mereka telah menyelesaikan transisi status:

Menyelesaikan

Beberapa sink media memerlukan langkah pemrosesan ekstra setelah sampel terakhir dikirimkan. Biasanya persyaratan ini berlaku untuk sink arsip, yang harus menulis header atau indeks ke dalam file. Jika sink media memerlukan pemrosesan akhir, sink akan mengekspos antarmuka IMFFinalizableMediaSink .

Setelah klien memberikan sampel terakhir, klien meminta antarmuka ini. Jika sink media mendukung antarmuka, klien memanggil IMFFinalizableMediaSink::BeginFinalize untuk melakukan pemrosesan akhir secara asinkron. Metode ini mengikuti model asinkron Media Foundation standar, yang dijelaskan dalam Metode Panggilan Balik Asinkron. Sink media dapat mengasumsikan bahwa klien akan memanggil BeginFinalize. Kegagalan untuk memanggil BeginFinalize dapat mengakibatkan file yang salah ditulis.

Mematikan

Ketika klien selesai menggunakan sink media, klien memanggil IMFMediaSink::Shutdown. Di dalam metode ini, sink media harus merusak jumlah referensi melingkar. Biasanya, akan ada referensi melingkar antara sink media dan sink aliran.

Jika Anda menggunakan objek pembantu antrean peristiwa untuk mengimplementasikan IMFMediaEventGenerator, panggil IMFMediaEventQueue::Shutdown pada antrean peristiwa. Metode ini mematikan antrean peristiwa dan memberi sinyal kepada penelepon apa pun yang saat ini menunggu peristiwa.

Setelah dimatikan, semua metode pada sink media mengembalikan MF_E_SHUTDOWN, dengan pengecualian metode IUnknown .

Antarmuka Sink Media

Tabel berikut mencantumkan antarmuka standar yang dapat diekspos sink media melalui QueryInterface. Sink media juga dapat mengekspos antarmuka kustom.

Antarmuka Deskripsi
IMFMediaSink Antarmuka utama untuk sink media. (Wajib)
IMFClockStateSink Digunakan untuk memberi tahu sink media ketika jam presentasi mengubah status. (Wajib)
IMFFinalizableMediaSink Terapkan jika sink media harus melakukan langkah pemrosesan akhir. (Opsional.)
IMFGetService Terapkan jika sink media mengekspos antarmuka layanan apa pun. (Opsional.)
IMFMediaEventGenerator Terapkan jika sink media mengirim peristiwa apa pun. (Opsional.)
IMFMediaSinkPreroll Terapkan jika sink media mendukung pra-pendaftaran. (Opsional.)
IMFPresentationTimeSource Terapkan jika sink media dapat menyediakan sumber waktu untuk jam presentasi. (Opsional.)
IMFQualityAdvise Terapkan jika sink media dapat menyesuaikan kualitas pemutaran. (Opsional.)

 

Secara opsional, sink media dapat mengimplementasikan antarmuka berikut sebagai layanan.

Antarmuka layanan Deskripsi
IMFRateSupport Melaporkan rentang laju pemutaran yang didukung.

 

Untuk informasi selengkapnya tentang antarmuka layanan dan IMFGetService, lihat Antarmuka Layanan.

Streaming Antarmuka Sink

Stream sink harus mengekspos antarmuka berikut melalui QueryInterface.

Antarmuka Deskripsi
IMFStreamSink Antarmuka utama untuk sink aliran. (Wajib)
IMFMediaEventGenerator Peristiwa antrean. Antarmuka IMFStreamSink mewarisi antarmuka ini. (Wajib)

 

Saat ini tidak ada antarmuka layanan yang didefinisikan untuk sink aliran.

Streaming Peristiwa Sink

Tabel berikut mencantumkan peristiwa yang ditentukan untuk sink aliran generik. Stream sink juga dapat mengirim peristiwa kustom yang tidak tercantum di sini.

Kejadian Deskripsi
MEStreamSinkFormatChanged Jenis media stream sink tidak lagi valid. (Opsional.)
MEStreamSinkMarker Penanda diproses. (Wajib)
MEStreamSinkPaused Sink aliran telah dijeda. (Wajib)
MEStreamSinkPrerolled Preroll selesai. (Opsional.)
MEStreamSinkRateChanged Sink streaming telah mengubah laju pemutaran. (Opsional.)
MEStreamSinkRequestSample Sampel baru diminta. (Wajib)
MEStreamSinkScrubSampleComplete Permintaan scrub selesai. (Opsional.)
MEStreamSinkStarted Sink aliran telah dimulai. (Wajib)
MEStreamSinkStopped Sink aliran telah berhenti. (Wajib)

 

Saat ini tidak ada peristiwa tujuan umum yang didefinisikan untuk sink media. Beberapa sink media mungkin mengirim peristiwa kustom.

Alur Media Foundation

Arsitektur Media Foundation