Flusso di dati nello strumento di navigazione DVD
[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation invece di DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.
Lo strumento di navigazione DVD include metodi per arrestare e sospendere la riproduzione. Questi metodi sono simili, ma non identici, ai metodi Stop e Pause in IMediaControl. Ecco la differenza tra di esse:
- I metodi IControl2 modificano ciò che lo strumento di navigazione DVD legge dal disco. Non modificano lo stato del grafico.
- I metodi IMediaControl modificano lo stato del grafico. Non cambiano ciò che lo strumento di navigazione DVD legge dal disco. È presente un'eccezione importante, illustrata nella sezione successiva, correlata al metodo Stop .
Ad esempio, il metodo IDeviceControl2::P ause esegue il comando "Pause_On" allegato J, ma non sospende il grafico del filtro. Il metodo IMediaControl::P ause , d'altra parte, sospende il grafico ma non esegue alcun comando DVD.
In generale, usare i metodi IMediaControl::P ause e Stop anziché i metodi IDeviceControl2 corrispondenti. I metodi IMediaControl hanno latenze molto piccole, mentre i metodi IControl2 possono avere fino a due secondi di latenza.
Arresto della riproduzione
Il comportamento di IMediaControl::Stop dipende da un flag che è possibile impostare con il metodo IDeviceControl2::SetOption .
- Se il flag DVD_ResetOnStop è FALSE, IMediaControl::Stop arresta il grafico, ma non modifica il dominio di DVD Navigator. Quando si chiama di nuovo l'esecuzione, la riproduzione riprende dalla posizione corrente.
- Se DVD_ResetOnStop è TRUE, IMediaControl::Stop fa sì che lo strumento di spostamento DVD venga reimpostato. Quando chiami di nuovo IMediaControl::Run , lo strumento di navigazione DVD viene riprodotto dal dominio First Play, come se avessi inserito il DVD per la prima volta.
Il flag DVD_ResetOnStop è TRUE per impostazione predefinita, per compatibilità con le applicazioni meno recenti. In genere, tuttavia, è necessario eseguire l'override del valore predefinito e impostare il flag su FALSE. Il motivo è che determinati eventi possono causare l'arresto del grafico durante la riproduzione. Ad esempio, se la risoluzione dello schermo cambia, il grafico del filtro si arresta, riconnette il renderer video e riavvia. Se DVD_ResetOnStop è TRUE, la riproduzione verrà riavviata dall'inizio del disco. Questo probabilmente non è ciò che l'utente si aspetta.
All'inizio dell'applicazione chiamare quindi SetOption con DVD_ResetOnStop impostato su FALSE. Se vuoi arrestare la riproduzione e riattivarla dalla stessa posizione, chiama IMediaControl::Stop o IMediaControl::P ause. Se vuoi interrompere la riproduzione e reimpostare il disco, chiama SetOption con DVD_ResetOnStop uguale a TRUE; quindi chiamare IMediaControl::Stop; infine, chiamare di nuovo SetOption e reimpostare DVD_ResetOnStop su FALSE.
Sospensione della riproduzione
Se si assegna al DVD Navigator un comando mentre il grafico è sospeso, il comando potrebbe non completare fino a quando il grafico non viene eseguito di nuovo. In alcune situazioni, questo può causare un deadlock nell'applicazione. Esistono due regole da seguire per evitare deadlock:
- Durante la sospensione, non eseguire più di un comando DVD asincrono.
- Durante la sospensione, non bloccare il thread dell'interfaccia utente dell'applicazione o il thread che modifica lo stato del grafico.
La seconda regola vale la pena esaminare in modo più dettagliato. Ecco alcuni scenari specifici che possono causare un deadlock:
Scenario: durante la sospensione, l'applicazione invia un comando DVD con il flag di blocco. Ciò può causare un deadlock se il thread che emette il comando DVD è lo stesso thread che emette il comando di esecuzione. Il comando DVD si blocca fino all'esecuzione del grafico, ma il grafico non può essere eseguito fino al completamento del comando.
Raccomandazione: eseguire il comando DVD in un thread di lavoro separato o non usare il flag di blocco.
Scenario: durante la sospensione, l'applicazione emette un comando DVD, quindi chiama I DistribuitCmd::WaitForEnd sull'oggetto comando. Questa situazione equivale all'esempio precedente. Se si chiama Wait dal thread dell'interfaccia utente, il thread dell'interfaccia utente non può eseguire il grafico fino a quando il metodo Wait non viene sbloccato, ma il metodo Wait non verrà sbloccato fino all'esecuzione del grafico.
Raccomandazione: chiamare l'attesa su un thread di lavoro.
Scenario: mentre il grafico è in esecuzione, l'applicazione emette un comando DVD con il flag di blocco e quindi chiama pause da un altro thread. Si tratta di una possibile race condition perché il grafico può sospendere prima dell'esecuzione del comando. Se uno dei due thread è il thread dell'interfaccia utente, è possibile che si verifichi un deadlock simile ai due esempi precedenti. Questo esempio illustra l'importanza della scrittura di codice thread-safe se l'applicazione usa più thread.
Raccomandazione: se si usano thread di lavoro, assicurarsi che il codice sia thread-safe.
Scenario: durante la sospensione, l'applicazione disabilita il comando run dall'interfaccia utente e quindi invia un comando DVD asincrono. Questo caso non è strettamente un deadlock, perché il thread dell'applicazione è ancora in esecuzione. Tuttavia, all'utente viene impedito di eseguire il grafico e pertanto il comando non verrà mai completato.
Raccomandazione: quando si sospendo, lasciare sempre abilitato il comando di esecuzione.
Ricerca di un DVD in un'ora specificata
Per cercare in modo accurato un'ora specificata in un disco, chiamare IMediaControl::Run. Chiamare quindi IDeviceControl2::P layAtTime, specificando l'ora e impostando dwFlags su DVD_CMD_FLAG_Flush.
Argomenti correlati