Menyinkronkan Perintah DVD
[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Pengambilan 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 Pengambilan Audio/Video 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.]
Perintah DVD tidak selalu selesai secara instan. Untuk alasan ini, beberapa metode dalam IDvdControl2 asinkron. Ini termasuk metode pemutaran, seperti PlayTitle, dan metode navigasi menu, seperti ShowMenu dan ReturnFromSubmenu. Metode asinkron segera kembali, tanpa menunggu perintah selesai. Setelah metode kembali, peristiwa lain dapat mencegah perintah selesai, bahkan jika metode berhasil. DirectShow menyediakan beberapa opsi untuk menyinkronkan perintah, mulai dari tidak ada sinkronisasi hingga sinkronisasi penuh menggunakan peristiwa grafik filter.
Semua metode-metode asinkron memiliki parameter dwFlags dan parameter ppCmd. Parameter dwFlags menentukan perilaku sinkronisasi, dan parameter ppCmd mengembalikan penunjuk ke objek sinkronisasi opsional. Hasil perilaku yang berbeda tergantung pada nilai apa yang Anda berikan untuk parameter ini.
Tidak Ada Sinkronisasi
Untuk aplikasi pemutaran DVD dasar, opsi terbaik mungkin hanya untuk mengabaikan masalah sinkronisasi. Kadang-kadang perintah mungkin gagal atau antarmuka pengguna (UI) dapat sedikit tertunda saat diperbarui, tetapi kesalahan ini biasanya hanya berlangsung dalam hitungan pecahan detik.
Untuk mengeluarkan perintah tanpa sinkronisasi, atur bendera DVD_CMD_FLAG_None di parameter dwFlags dan atur parameter ppCmd ke NULL:
hr = pDVDControl2->PlayTitle(uTitle, DVD_CMD_FLAG_None, NULL);
Pemblokiran
Jika Anda mengatur flag EC_DVD_CMD_FLAG_Block di parameter dwFlags, metode tersebut akan memblokir hingga perintah selesai.
hr = pDVDControl2->PlayTitle(uTitle, EC_DVD_CMD_FLAG_Block, NULL);
Akibatnya, bendera ini mengubah metode asinkron menjadi metode sinkron. Kelemahannya adalah antarmuka pengguna Anda akan terblokir jika Anda memanggil metode dari utas aplikasi.
Objek Sinkronisasi
Semua metode asinkron dapat mengembalikan objek sinkronisasi, yang dapat Anda gunakan untuk menunggu perintah dimulai atau berakhir. Untuk mendapatkan objek ini, berikan alamat penunjuk IDvdCmd dalam parameter ppCmd:
IDvdCmd *pCmdObj = NULL;
hr = pDVDControl2->PlayTitle(uTitle, DVD_CMD_FLAG_None, &pCmdObj);
Jika metode berhasil, metode mengembalikan objek IDvdCmd baru. Metode IDvdCmd::WaitForStart memblokir hingga perintah dimulai, dan metode IDvdCmd::WaitForEnd memblokir hingga perintah berakhir. Nilai pengembalian menunjukkan status perintah.
Kode berikut secara fungsional setara dengan mengatur bendera EC_DVD_CMD_FLAG_Block, yang ditunjukkan sebelumnya.
IDvdCmd *pCmdObj = NULL;
hr = pDVDControl2->PlayTitle(uTitle, DVD_CMD_FLAG_None, &pCmdObj);
if (SUCCEEDED(hr))
{
// Use pCmdObj to wait for the command to complete.
hr = pCmdObj->WaitToEnd();
pCmdObj->Release();
}
Dalam hal ini, metode PlayTitle tidak memblokir, tetapi aplikasi memblokir dengan memanggil WaitForEnd.
Peristiwa Status Perintah
Jika Anda mengatur bendera DVD_CMD_FLAG_SendEvents di parameter dwFlags, DVD Navigator mengirimkan peristiwa EC_DVD_CMD_START saat perintah dimulai dan peristiwa EC_DVD_CMD_END saat perintah berakhir.
Parameter lParam2 peristiwa adalah nilai pengembalian HRESULT untuk perintah . Parameter lParam1 peristiwa menyediakan cara untuk mendapatkan objek sinkronisasi untuk perintah. Jika Anda meneruskan lParam1 ke metodeIDvdInfo2::GetCmdFromEvent, metode mengembalikan penunjuk ke antarmuka IDvdCmd objek sinkronisasi. Anda dapat menggunakan antarmuka ini untuk menunggu penyelesaian perintah, seperti yang dijelaskan sebelumnya. Namun, jika Anda meneruskan NULL untuk parameter ppCmd dalam metode asli IDvdControl2, DVD Navigator tidak membuat objek sinkronisasi, dan GetCmdFromEvent mengembalikan E_FAIL.
Kode berikut menunjukkan cara menggunakan peristiwa status perintah tanpa objek sinkronisasi.
hr = pDVDControl2->PlayTitle(uTitle, DVD_CMD_FLAG_SendEvents, NULL);
// In your event handling code:
switch (lEvent)
{
case EC_DVD_CMD_END:
HRESULT hr2 = (HRESULT)lParam2;
/* ... */
break;
}
Perhatikan bahwa tanpa objek sinkronisasi, Anda tidak dapat mengetahui perintah mana yang terkait dengan peristiwa. Kode berikut menunjukkan cara menggunakan peristiwa dengan objek sinkronisasi. Idenya adalah menyimpan objek sinkronisasi dalam daftar lalu membandingkan penunjuk objek saat Anda mendapatkan peristiwa EC_DVD_CMD_START atau EC_DVD_CMD_END.
IDvdCmd *pCmdObj = NULL;
hr = pDVDControl2->PlayTitle(uTitle, DVD_CMD_FLAG_SendEvents, &pCmdObj);
if (SUCCEEDED(hr))
{
// Store pCmdObj in a list of pending commands.
}
// In your event handling code:
switch (lEvent)
{
case EC_DVD_CMD_END:
{
IDvdCmd *pObj = NULL;
hr = pDvdInfo2->GetCmdFromEvent(lParam, &pObj);
if (SUCCEEDED(hr))
{
// Find this object in your list by comparing IUnknown
// pointers. Assume the following function is defined in
// your application:
IDvdCmd *pPendingObj = GetPendingCommandFromList(pObj);
if (pPendingObj)
{
// Update UI accordingly (not shown).
pPendingObj->Release();
}
pObj->Release();
}
}
break;
}
Mengosongkan Buffer Navigator DVD
Selama pemutaran, DVD Navigator menyangga data video. Jumlah data yang di-buffer bervariasi. Ketika DVD Navigator beralih ke bagian video baru, data yang sudah ada di alur tidak hilang, sehingga transisi mulus. Secara default, ketika DVD Navigator mengeluarkan perintah, DVD Navigator tidak menghapus data yang sudah ada di alur. Akibatnya, mungkin ada beberapa latensi sebelum Anda dapat melihat efek perintah, tergantung pada berapa banyak data yang di-buffer. Untuk meningkatkan responsivitas, Anda dapat memaksa DVD Navigator untuk membersihkan dengan mengatur parameter DVD_CMD_FLAG_Flush.
hr = pDVDControl2->PlayTitle(uTitle, DVD_CMD_FLAG_Flush, NULL);
Bendera ini dapat dikombinasikan dengan salah satu bendera yang dijelaskan sebelumnya, menggunakan bitwise OR. Efek samping dari pembilasan adalah bahwa beberapa video mungkin hilang, jadi jangan gunakan bendera ini jika Anda perlu menjamin tidak ada celah dalam video.