DVD-parancsok szinkronizálása
[A laphoz társított funkció, DirectShowegy régi funkció. "Ezt felváltotta a MediaPlayer, a IMFMediaEngine, és a Audio/Video Capture a Media Foundation." Ezek a funkciók Windows 10-hez és Windows 11-hez lettek optimalizálva. A Microsoft határozottan javasolja, hogy az új kód a MediaPlayer-t, a IMFMediaEngine-at és a Media Foundation Audio/Video Capture-t használja a DirectShowhelyett, ha lehetséges. A Microsoft javasolja, hogy az örökölt API-kat használó meglévő kódot át kell írni az új API-k használatára, ha lehetséges.]
A DVD-parancsok nem mindig fejeződnek be azonnal. Ezért az IDvdControl2 néhány metódusa aszinkron. Ezek közé tartoznak a lejátszási módszerek, például a PlayTitle, valamint a menünavigációs módszerek, például ShowMenu és ReturnFromSubmenu. Az aszinkron metódus azonnal, a parancs befejezésére való várakozás nélkül tér vissza. A metódus visszatérése után más események megakadályozhatják a parancs végrehajtását, még akkor is, ha a metódus sikeres volt. A DirectShow számos lehetőséget kínál a parancsok szinkronizálására, a szinkronizálás nélkülitől a teljes szinkronizálásig a szűrőgráfesemények használatával.
Az összes aszinkron metódus rendelkezik egy dwFlags paraméterrel és egy ppCmd paraméterrel. A dwFlags paraméter határozza meg a szinkronizálási viselkedést, a ppCmd paraméter pedig egy tetszőleges szinkronizálási objektumra mutató mutatót ad vissza. A különböző viselkedések attól függenek, hogy milyen értékeket ad ezeknek a paramétereknek.
Nincs szinkronizálás
Az alapszintű DVD-lejátszó alkalmazások esetében a legjobb megoldás lehet egyszerűen a szinkronizálási problémák figyelmen kívül hagyása. Előfordulhat, hogy egy parancs meghiúsul, vagy a felhasználói felület kissé eltelik a frissítéskor, de ezek a hibák másodperc törtek sorrendjében jelennek meg.
Ha szinkronizálás nélküli parancsot szeretne kiadni, állítsa be a DVD_CMD_FLAG_None jelzőt a dwFlags paraméterben, és állítsa a ppCmd paramétert a NULL :
hr = pDVDControl2->PlayTitle(uTitle, DVD_CMD_FLAG_None, NULL);
Blokkolás
Ha a EC_DVD_CMD_FLAG_Block jelzőt a dwFlags paraméterben állítja be, a metódus letiltja a parancs befejezéséig:
hr = pDVDControl2->PlayTitle(uTitle, EC_DVD_CMD_FLAG_Block, NULL);
Ez a jelző tulajdonképpen szinkron metódussá változtatja az aszinkron metódust. A hátránya, hogy a felhasználói felület blokkolja, ha meghívja a metódust az alkalmazásszálból.
szinkronizálási objektum
Az összes aszinkron metódus visszaadhat egy szinkronizálási objektumot, amellyel megvárhatja, amíg a parancs elindul vagy befejeződik. Az objektum lekéréséhez adja meg egy IDvdCmd mutató címét a ppCmd paraméterben:
IDvdCmd *pCmdObj = NULL;
hr = pDVDControl2->PlayTitle(uTitle, DVD_CMD_FLAG_None, &pCmdObj);
Ha a metódus sikeres, egy új IDvdCmd objektumot ad vissza. A IDvdCmd::WaitForStart metódusblokkok a parancs kezdetéig, és a IDvdCmd::WaitForEnd metódusblokkok a parancs végéig. A visszatérési érték a parancs állapotát jelzi.
Az alábbi kód funkcionálisan egyenértékű a korábban bemutatott EC_DVD_CMD_FLAG_Block jelző beállításával.
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();
}
Ebben az esetben a PlayTitle metódus nem utasítja el a blokkolást, de az alkalmazás a WaitForEndhívásával blokkol.
Parancsállapot-Események
Ha a DVD_CMD_FLAG_SendEvents jelzőt a dwFlags paraméterben állítja be, a DVD-kezelő EC_DVD_CMD_START eseményt küld a parancs kezdetekor, és egy EC_DVD_CMD_END eseményt, amikor a parancs véget ér.
Az esemény lParam2 paramétere a parancs HRESULT visszatérési értéke. Az esemény lParam1 paramétere lehetővé teszi a parancs szinkronizálási objektumának lekérését. Ha lParam1 továbbítja az IDvdInfo2::GetCmdFromEvent metódusnak, a metódus egy mutatót ad vissza a szinkronizálási objektum IDvdCmd felületére. Ezzel a felülettel megvárhatja a parancs befejezését a korábban leírtak szerint. Ha az eredeti IDvdControl2 metódusban a ppCmd paraméterhez NULL-t ad meg, akkor azonban a DVD Navigator nem fog szinkronizációs objektumot létrehozni, és a GetCmdFromEvent az E_FAIL hibakódot adja vissza.
Az alábbi kód bemutatja, hogyan használhatja a parancsállapot-eseményeket szinkronizálási objektum nélkül.
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;
}
Vegye figyelembe, hogy szinkronizálási objektum nélkül nem lehet megállapítani, hogy melyik parancs van társítva az eseményhez. Az alábbi kód bemutatja, hogyan használhat eseményeket a szinkronizálási objektummal. A cél az, hogy a szinkronizálási objektumokat egy listában tárolja, majd összehasonlítsa az objektummutatókat a EC_DVD_CMD_START vagy EC_DVD_CMD_END esemény lekérésekor.
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;
}
DVD-kezelő puffereinek kiürítése
A dvd-kezelő a lejátszás során puffereli a videoadatokat. A pufferelt adatok mennyisége változó. Amikor a DVD Navigator egy új videóra vált, a folyamatban lévő adatok nem vesznek el, így az áttűnés zökkenőmentes. Alapértelmezés szerint, amikor a DVD Navigátor kiad egy parancsot, nem üríti ki az adatokat a csővezetéken. Ennek eredményeképpen előfordulhat némi késés, mielőtt láthatja a parancs hatását attól függően, hogy mennyi adat van pufferelve. A válaszképesség növeléséhez kényszerítheti a DVD-navigátort a DVD_CMD_FLAG_Flush jelző beállításával.
hr = pDVDControl2->PlayTitle(uTitle, DVD_CMD_FLAG_Flush, NULL);
Ez a jelző kombinálható a korábban ismertetett jelzőkkel, a bitwise OR művelet használatával. Az adatok kiürítésének egyik mellékhatása, hogy egyes videótartalmak elveszhetnek, ezért ne használja ezt a jelzőt, ha garantálnia kell, hogy nincsenek rések a videóban.
Kapcsolódó témakörök