Mengirimkan Sampel
[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Tangkapan Audio/Video di Media Foundation. Fitur-fitur tersebut telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer, IMFMediaEngine dan Audio/Video Capture di Media Foundation alih-alih DirectShow, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]
Artikel ini menjelaskan bagaimana filter memberikan sampel. Ini menjelaskan model pendorongan, menggunakan metode IMemInputPin , dan model penarikan, menggunakan IAsyncReader.
Model Pendorongan: Mengirimkan Sampel
Pin output memberikan sampel dengan memanggil metode IMemInputPin::Receive atau metode IMemInputPin::ReceiveMultiple , yang setara tetapi memberikan array sampel. Pin input dapat diblokir di dalam Receive (atau ReceiveMultiple). Jika pin mungkin memblokir, metode IMemInputPin::ReceiveCanBlock-nya harus mengembalikan S_OK. Jika pin menjamin tidak pernah memblokir, ReceiveCanBlock harus mengembalikan S_FALSE. Nilai pengembalian S_OK tidak berarti bahwa Terima selalu diblokir, hanya saja mungkin.
Meskipun Terima dapat memblokir untuk menunggu sumber daya tersedia, seharusnya tidak memblokir untuk menunggu lebih banyak data dari filter upstram. Melakukannya dapat menyebabkan kebuntuan di mana filter upstram menunggu filter hilir melepaskan sampel, yang tidak pernah terjadi karena filter hilir menunggu filter upstream. Namun, jika filter memiliki beberapa pin input, satu pin dapat menunggu pin lain menerima data. Misalnya, filter AVI Mux melakukan ini sehingga dapat mengintervensi data audio dan video.
Pin mungkin menolak sampel karena sejumlah alasan:
- Pin memerah (lihat Pembiringan).
- Pin tidak tersambung.
- Filter dihentikan.
- Terjadi beberapa kesalahan lainnya.
Metode Terima harus mengembalikan S_FALSE dalam kasus pertama, dan kode kegagalan dalam kasus lain. Filter upstram harus berhenti mengirim sampel ketika kode yang dikembalikan adalah apa pun selain S_OK.
Anda dapat menganggap tiga kasus pertama adalah kegagalan "diharapkan", dalam arti filter berada dalam status yang salah untuk menerima sampel. Kegagalan yang tidak terduga adalah kegagalan yang menyebabkan pin menolak sampel meskipun pin dalam keadaan menerima. Jika kesalahan jenis ini terjadi, pin harus mengirim pemberitahuan akhir aliran ke hilir, dan mengirim peristiwa EC_ERRORABORT ke Filter Graph Manager.
Di kelas dasar DirectShow, metode CBaseInputPin::CheckStreaming memeriksa kasus kegagalan umum—pembersihan, dihentikan, dan sebagainya. Kelas turunan perlu memeriksa kegagalan yang khusus untuk filter. Jika terjadi kesalahan, metode CBaseInputPin::Receive mengirimkan pemberitahuan akhir aliran dan peristiwa EC_ERRORABORT.
Model Penarikan: Meminta Sampel
Di antarmuka IAsyncReader , pin input meminta sampel dari pin output dengan memanggil salah satu metode berikut:
Metode Permintaan bersifat asinkron; pin input memanggil IAsyncReader::WaitForNext untuk menunggu permintaan selesai. Dua metode lainnya sinkron.
Kapan Harus Mengirimkan Data
Filter selalu mengirimkan sampel saat berada dalam status berjalan. Dalam kebanyakan kasus, filter juga memberikan sampel saat dijeda. Ini memungkinkan grafik untuk memisah data sehingga pemutaran segera dimulai saat Eksekusi dipanggil (lihat Status Filter). Jika filter Anda tidak mengirimkan data saat dijeda, metode IMediaFilter::GetState filter harus mengembalikan VFW_S_CANT_CUE dalam status dijeda. Kode pengembalian ini memberi sinyal grafik filter untuk tidak menunggu data dari filter Anda sebelum menyelesaikan transisi jeda. Jika tidak, metode Jeda akan memblokir tanpa batas waktu. Misalnya kode, lihat CBaseFilter::GetState.
Berikut adalah beberapa contoh kapan filter mungkin perlu mengembalikan VFW_S_CANT_CUE:
- Sumber langsung, seperti filter pengambilan, tidak boleh mengirim data saat dijeda. Lihat Menghasilkan Data dalam Filter Pengambilan.
- Filter pemisah mungkin atau mungkin tidak mengirim data saat dijeda, tergantung pada implementasinya. Jika filter menggunakan utas terpisah untuk mengantre data pada setiap pin output, filter dapat mengirim data saat dijeda. Tetapi jika filter menggunakan satu utas untuk setiap pin output, pin pertama mungkin memblokir utas saat memanggil Terima, yang akan mencegah pin lain mengirim data. Dalam hal ini, Anda harus mengembalikan VFW_S_CANT_CUE.
- Filter mungkin mengirimkan data secara sporadis. Misalnya, mungkin mengurai aliran data kustom dan memfilter beberapa paket saat mengirimkan yang lain. Dalam hal ini, filter mungkin tidak dijamin untuk mengirimkan data saat dijeda.
Filter sumber (menggunakan model pendorongan) atau filter pengurai (menggunakan model pendorongan/penarikan) membuat satu atau beberapa utas streaming, yang mengirimkan sampel secepat mungkin. Filter hilir, seperti dekoder dan transformasi, biasanya hanya mengirim data saat Terima dipanggil pada pin inputnya.
Topik terkait