Compartilhar via


Liberando

[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo 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 Captura de Áudio/Vídeo 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.]

Enquanto o grafo de filtro está em execução, quantidades arbitrárias de dados podem estar se movendo pelo grafo. Algumas delas podem estar em filas, aguardando para serem entregues. Há momentos em que o grafo de filtro precisa remover esses dados pendentes o mais rápido possível e substituí-los por novos dados. Após um comando seek, por exemplo, o filtro de origem gera exemplos de uma nova posição na origem. Para minimizar a latência, os filtros downstream devem descartar todos os exemplos que foram criados antes do comando seek. O processo de descarte de amostras é chamado de liberação. Ele permite que o grafo seja mais responsivo quando os eventos alteram o fluxo de dados normal.

A liberação é tratada de forma ligeiramente diferente pelo modelo de pull do que o modelo de push. Este artigo começa descrevendo o modelo de push; em seguida, ele descreve as diferenças no modelo de pull.

A liberação ocorre em dois estágios.

  • Primeiro, o filtro de origem chama IPin::BeginFlush no pino de entrada do filtro downstream. O filtro downstream começa a rejeitar amostras de upstream. Ele também descarta todos os exemplos que está segurando e envia a chamada BeginFlush downstream para o próximo filtro.
  • Quando o filtro de origem estiver pronto para enviar novos dados, ele chamará IPin::EndFlush no pin de entrada. Isso sinaliza o filtro downstream que ele pode receber novos exemplos. O filtro downstream envia a chamada EndFlush para o próximo filtro.

No método BeginFlush , o pin de entrada faz o seguinte:

  1. Chama BeginFlush em pinos de entrada downstream.
  2. Rejeita as chamadas adicionais que transmitem dados, incluindo Receive e EndOfStream.
  3. Desbloqueia todos os filtros de upstream bloqueados aguardando um exemplo do alocador do filtro. Alguns filtros descompromissam seus alocadores para essa finalidade.
  4. Sai de todas as esperas que bloqueiam o streaming. Por exemplo, os filtros de renderizador são bloqueados quando pausados. Eles também bloqueiam quando estão esperando para renderizar uma amostra no tempo de fluxo correto. O filtro deve ser desbloqueado para que exemplos enfileirados upstream possam ser entregues e rejeitados. Esta etapa garante que todos os filtros de upstream eventualmente desbloqueiem.

No método EndFlush , o pin de entrada faz o seguinte:

  1. Aguarda que todos os exemplos enfileirados sejam descartados.
  2. Libera todos os dados armazenados em buffer. Às vezes, essa etapa pode ser executada no método BeginFlush . No entanto, BeginFlush não é sincronizado com o thread de streaming. O filtro não deve processar nem armazenar em buffer mais dados entre a chamada para BeginFlush e a chamada para EndFlush.
  3. Limpa as notificações de EC_COMPLETE pendentes.
  4. Chama EndFlush downstream.

Neste ponto, o filtro pode aceitar amostras novamente. Todos os exemplos têm a garantia de serem mais recentes do que a liberação.

No modelo de pull, o filtro do analisador inicia a liberação, em vez do filtro de origem. Além de chamar IPin::BeginFlush e IPin::EndFlush no filtro downstream, ele também chama IAsyncReader::BeginFlush e IAsyncReader::EndFlush no pino de saída do filtro de origem. Se o filtro de origem tiver solicitações de leitura pendentes, ele as descartará.

Liberando dados