Compartilhar via


Fluxo de dados no Navegador de DVD

[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEnginee Audio/Video Capture na Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Audio/Video Capture no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

O Navegador de DVD tem métodos para parar e pausar a reprodução. Esses métodos são semelhantes , mas não idênticos, aos métodos Stop e Pause em IMediaControl. Aqui está a diferença entre eles:

  • Os métodos IDvdControl2 alteram o que o Navegador de DVD lê do disco. Eles não alteram o estado do grafo.
  • Os métodos de IMediaControl alteram o estado do grafo. Eles não alteram o que o Navegador de DVD lê do disco. (Há uma exceção importante, explicada na próxima seção, relacionada ao método Stop.)

Por exemplo, método IDvdControl2::P ause emite o comando "Pause_On" do Anexo J, mas não pausa o grafo de filtro. O método IMediaControl::P ause, por outro lado, pausa o grafo, mas não emite nenhum comando de DVD.

Em geral, use os métodos IMediaControl::P ause e Stop em vez dos métodos de IDvdControl2 correspondentes. Os métodos de IMediaControl têm latências muito pequenas, enquanto os métodos de IDvdControl2 podem ter até dois segundos de latência.

Interrompendo a reprodução

O comportamento de IMediaControl::Stop depende de um sinalizador que você pode definir com o método IDvdControl2::SetOption.

  • Se o sinalizador DVD_ResetOnStop for FALSE, IMediaControl::Parar interromperá o grafo, mas não alterará o domínio do Dvd Navigator. Quando você chama executar novamente, a reprodução é retomada da posição atual.
  • Se DVD_ResetOnStop for TRUE, IMediaControl::Stop fará com que o Navegador de DVD seja redefinido. Quando você chama IMediaControl::Run novamente, o Navegador de DVD é reproduzido no domínio First Play, como se estivesse inserindo o DVD pela primeira vez.

O sinalizador DVD_ResetOnStop é verdadeiro por padrão, para compatibilidade com aplicativos mais antigos. Geralmente, no entanto, você deve substituir o padrão e definir o sinalizador como false. O motivo é que determinados eventos podem fazer com que o grafo pare durante a reprodução. Por exemplo, se a resolução de exibição for alterada, o grafo de filtro será interrompido, reconectará o renderizador de vídeo e reiniciará. Se DVD_ResetOnStop for TRUE, a reprodução será reiniciada desde o início do disco. Isso provavelmente não é o que o usuário espera.

No início do aplicativo, portanto, chame SetOption com DVD_ResetOnStop definido como FALSE. Se você quiser interromper a reprodução e retomá-la do mesmo local, chame IMediaControl::Parar ou IMediaControl::P ause. Se você quiser interromper a reprodução e redefinir o disco, chame SetOption com DVD_ResetOnStop igual a TRUE; em seguida, chame IMediaControl::Stop; por fim, chame SetOption novamente e redefina DVD_ResetOnStop para FALSE.

Pausando a Reprodução

Se você conceder um comando ao Navegador de DVD enquanto o grafo estiver em pausa, o comando poderá não ser concluído até que o grafo seja executado novamente. Em algumas situações, isso pode causar um deadlock em seu aplicativo. Há duas regras que você deve seguir para evitar deadlocks:

  • Durante a pausa, não emita mais de um comando de DVD assíncrono.
  • Durante a pausa, não bloqueie o thread da interface do usuário do aplicativo ou o thread que altera o estado do grafo.

Vale a pena examinar a segunda regra com mais detalhes. Aqui estão alguns cenários específicos que podem causar um deadlock:

  • Cenário: enquanto pausado, o aplicativo emite um comando dvd com o sinalizador de bloqueio. Isso poderá causar um deadlock se o thread que emite o comando DVD for o mesmo thread que emite o comando de execução. O comando DVD é bloqueado até que o grafo seja executado, mas o grafo não poderá ser executado até que o comando seja concluído.

    Recomendação: emita o comando DVD em um thread de trabalho separado ou não use o sinalizador de bloqueio.

  • Cenário: enquanto pausado, o aplicativo emite um comando de DVD e, em seguida, chama IDvdCmd::WaitForEnd no objeto de comando. Essa situação é equivalente ao exemplo anterior. Se você chamar Wait do thread da interface do usuário, o thread da interface do usuário não poderá executar o grafo até que o método Wait seja desbloqueado, mas o método Wait não será desbloqueado até que o grafo seja executado.

    de recomendação de: chame wait em um thread de trabalho.

  • Cenário: enquanto o grafo está em execução, o aplicativo emite um comando dvd com o sinalizador de bloqueio e, em seguida, chama pausa de outro thread. Essa é uma possível condição de corrida porque o grafo pode pausar antes que o comando seja emitido. Se um dos dois threads for o thread de interface do usuário, você poderá causar um deadlock semelhante aos dois exemplos anteriores. Este exemplo ilustra a importância de escrever código thread-safe se o aplicativo usar vários threads.

    Recomendação: se você usar threads de trabalho, verifique se o código é thread-safe.

  • Cenário: enquanto pausado, o aplicativo desabilita o comando de execução da interface do usuário e emite um comando de DVD assíncrono. Esse caso não é estritamente um deadlock, pois o thread do aplicativo ainda está em execução. No entanto, o usuário agora está impedido de executar o grafo e, portanto, o comando nunca será concluído.

    Recomendação: ao pausar, sempre deixe o comando de execução habilitado.

Buscando um DVD para um horário especificado

Para buscar com precisão uma hora especificada em um disco, chame IMediaControl::Run. Em seguida, chame IDvdControl2::P layAtTime, especificando a hora e a configuração dwFlags para DVD_CMD_FLAG_Flush.

aplicativos de DVD