Data Flow en el navegador de DVD

[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.

El navegador de DVD tiene métodos para detener y pausar la reproducción. Estos métodos son similares, pero no idénticos, a los métodos Stop y Pause de IMediaControl. Esta es la diferencia entre ellos:

  • Los métodos IDvdControl2 cambian lo que lee el navegador de DVD desde el disco. No cambian el estado del gráfico.
  • Los métodos IMediaControl cambian el estado del grafo. No cambian lo que lee el navegador de DVD desde el disco. (Hay una excepción importante, que se explica en la sección siguiente, relacionada con el método Stop ).

Por ejemplo, el método IDvdControl2::P ause emite el comando "Pause_On" del anexo J, pero no pausa el gráfico de filtros. El método IMediaControl::P ause , por otro lado, pausa el gráfico, pero no emite ningún comando de DVD.

En general, use los métodos IMediaControl::P ause y Stop en lugar de los métodos IDvdControl2 correspondientes. Los métodos IMediaControl tienen latencias muy pequeñas, mientras que los métodos IDvdControl2 pueden tener hasta dos segundos de latencia.

Detener la reproducción

El comportamiento de IMediaControl::Stop depende de una marca que se pueda establecer con el método IDvdControl2::SetOption .

  • Si la marca de DVD_ResetOnStop es FALSE, IMediaControl::Stop detiene el gráfico, pero no cambia el dominio del navegador de DVD. Al llamar a la ejecución de nuevo, la reproducción se reanuda desde la posición actual.
  • Si DVD_ResetOnStop es TRUE, IMediaControl::Stop hace que el navegador de DVD se restablezca. Cuando llamas a IMediaControl::Run de nuevo, el navegador de DVD se reproduce desde el dominio De primera reproducción, como si estuvieras insertando el DVD por primera vez.

La marca DVD_ResetOnStop es TRUE de forma predeterminada, por motivos de compatibilidad con aplicaciones anteriores. Sin embargo, por lo general, debe invalidar el valor predeterminado y establecer la marca en FALSE. El motivo es que determinados eventos pueden hacer que el gráfico se detenga durante la reproducción. Por ejemplo, si cambia la resolución de pantalla, el gráfico de filtros se detiene, vuelve a conectar el representador de vídeo y se reinicia. Si DVD_ResetOnStop es TRUE, la reproducción se reiniciará desde el principio del disco. Es probable que no sea lo que espera el usuario.

Al principio de la aplicación, llame a SetOption con DVD_ResetOnStop establecido en FALSE. Si quieres detener la reproducción y reanudarla desde la misma ubicación, llama a IMediaControl::Stop o IMediaControl::P ause. Si desea detener la reproducción y restablecer el disco, llame a SetOption con DVD_ResetOnStop igual a TRUE; a continuación, llame a IMediaControl::Stop; por último, vuelva a llamar a SetOption y restablezca DVD_ResetOnStop en FALSE.

Pausar reproducción

Si asigna al Navegador de DVD un comando mientras el grafo está en pausa, es posible que el comando no se complete hasta que el grafo se vuelva a ejecutar. En algunas situaciones, esto puede provocar un interbloqueo en la aplicación. Hay dos reglas que debe seguir para evitar interbloqueos:

  • Mientras está en pausa, no emita más de un comando de DVD asincrónico.
  • Mientras está en pausa, no bloquee el subproceso de interfaz de usuario de la aplicación ni el subproceso que cambie el estado del gráfico.

La segunda regla vale la pena examinar con más detalle. Estos son algunos escenarios específicos que pueden provocar un interbloqueo:

  • Escenario: mientras está en pausa, la aplicación emite un comando de DVD con la marca de bloqueo. Esto puede provocar un interbloqueo si el subproceso que emite el comando dvd es el mismo subproceso que emite el comando de ejecución. El comando dvd se bloquea hasta que se ejecuta el grafo, pero el gráfico no se puede ejecutar hasta que se complete el comando.

    Recomendación: Emita el comando dvd en un subproceso de trabajo independiente o no use la marca de bloqueo.

  • Escenario: mientras está en pausa, la aplicación emite un comando de DVD y, a continuación, llama a IDvdCmd::WaitForEnd en el objeto de comando. Esta situación es equivalente al ejemplo anterior. Si llama a Wait desde el subproceso de la interfaz de usuario, el subproceso de interfaz de usuario no puede ejecutar el grafo hasta que se desbloquee el método Wait , pero el método Wait no se desbloqueará hasta que se ejecute el grafo.

    Recomendación: Llame a Wait en un subproceso de trabajo.

  • Escenario: mientras se ejecuta el grafo, la aplicación emite un comando de DVD con la marca de bloqueo y, a continuación, llama a pausa desde otro subproceso. Se trata de una posible condición de carrera porque el grafo puede pausarse antes de que se emita el comando. Si uno de los dos subprocesos es el subproceso de interfaz de usuario, puede provocar un interbloqueo similar al de los dos ejemplos anteriores. En este ejemplo se muestra la importancia de escribir código seguro para subprocesos si la aplicación usa varios subprocesos.

    Recomendación: Si usa subprocesos de trabajo, asegúrese de que el código es seguro para subprocesos.

  • Escenario: mientras está en pausa, la aplicación deshabilita el comando de ejecución de la interfaz de usuario y, a continuación, emite un comando de DVD asincrónico. Este caso no es estrictamente un interbloqueo, ya que el subproceso de la aplicación todavía se está ejecutando. Sin embargo, ahora se impide que el usuario ejecute el grafo y, por lo tanto, el comando nunca se completará.

    Recomendación: al pausar, deje siempre habilitado el comando run.

Buscar un DVD a una hora especificada

Para buscar con precisión un tiempo especificado en un disco, llame a IMediaControl::Run. A continuación, llame a IDvdControl2::P layAtTime, especificando la hora y estableciendo dwFlags en DVD_CMD_FLAG_Flush.

Aplicaciones de DVD