Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEnginee Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda vivamente que o novo código utilize 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.]
Este artigo descreve como um filtro fornece uma amostra. Ele descreve tanto o modelo push, usando os métodos IMemInputPin , quanto o modelo pull, usando IAsyncReader .
Modelo Push: Entrega de uma amostra
O pino de saída fornece uma amostra chamando o método IMemInputPin::Receive ou o método IMemInputPin::ReceiveMultiple, que é equivalente, mas fornece uma matriz de amostras. O pino de entrada pode bloquear dentro de receber (ou receber múltiplos ). Se o pino pode bloquear, seu IMemInputPin::ReceiveCanBlock método deve retornar S_OK. Se o pino garante nunca se bloquear, ReceiveCanBlock deve retornar S_FALSE. O valor de retorno S_OK não indica que Receive bloqueia sempre, apenas que pode ocorrer.
Embora Receive possa bloquear para aguardar que um recurso fique disponível, ele não deve bloquear para aguardar mais dados do filtro a montante. Isso pode causar um impasse em que o filtro a montante aguarda que o filtro a jusante liberte a amostra, o que nunca ocorre porque o filtro a jusante está à espera do filtro a montante. No entanto, se um filtro tiver vários pinos de entrada, um pino poderá aguardar que outro pino receba dados. Por exemplo, o filtro AVI Mux faz isso para que possa intercalar dados de áudio e vídeo.
Um pino pode rejeitar uma amostra por vários motivos:
- O pino está a descarregar (ver Flushing).
- O pino não está conectado.
- O filtro está parado.
- Ocorreu algum outro erro.
O método Receive deve retornar S_FALSE no primeiro caso e um código de falha nos outros casos. O filtro upstream deve parar de enviar amostras quando o código de retorno for qualquer coisa diferente de S_OK.
Você pode considerar os três primeiros casos como falhas "esperadas", no sentido de que o filtro estava no estado errado para receber amostras. Uma falha inesperada seria aquela que faz com que o pino rejeite uma amostra mesmo que o pino esteja em um estado recetor. Se ocorrer um erro desse tipo, o pino deve enviar uma notificação de fim de fluxo a jusante e enviar um evento EC_ERRORABORT para o Gestor do Gráfico de Filtros.
Nas classes base do DirectShow, o método CBaseInputPin::CheckStreaming verifica os casos gerais de falha — como esvaziamento, paragem, e assim por diante. A classe derivada precisará verificar se há falhas específicas do filtro. Em caso de erro, o método CBaseInputPin::Receive envia a notificação de fim de fluxo e o evento EC_ERRORABORT.
Modelo Pull: Solicitando uma amostra
Na interface IAsyncReader, o pino de entrada solicita amostras do pino de saída ao chamar um dos seguintes métodos:
- IAsyncReader::Solicitação
- IAsyncReader::SyncRead
- IAsyncReader::SyncReadAligned
O método Request é assíncrono; o pino de entrada chama IAsyncReader::WaitForNext para aguardar a conclusão da solicitação. Os outros dois métodos são síncronos.
Quando entregar dados
Um filtro sempre entrega amostras enquanto está no estado de execução. Na maioria dos casos, um filtro também fornece amostras durante a pausa. Isso permite que o gráfico sinalize os dados para que a reprodução comece imediatamente quando Run é ativado (consulte Estados do filtro). Se o filtro não entregar dados durante a pausa, o método IMediaFilter::GetState do filtro deverá retornar VFW_S_CANT_CUE no estado pausado. Esse código de retorno sinaliza ao gráfico de filtro para não esperar pelos dados do filtro antes de concluir a transição de pausa. Caso contrário, o método Pause bloqueará indefinidamente. Para obter um código de exemplo, consulte CBaseFilter::GetState.
Aqui estão alguns exemplos de quando um filtro pode precisar retornar VFW_S_CANT_CUE:
- Fontes ativas, como filtros de captura, não devem enviar dados durante a pausa. Consulte Produzindo dados em um filtro de captura.
- Um filtro divisor pode ou não enviar dados durante a pausa, dependendo da implementação. Se o filtro usar threads separados para enfileirar dados em cada pino de saída, ele poderá enviar dados enquanto estiver pausado. Mas se o filtro usar um único tópico para todos os pinos de saída, o primeiro pino poderá bloquear o tópico quando chamar Receive, o que impedirá que os outros pinos enviem dados. Nesse caso, deverá devolver VFW_S_CANT_CUE.
- Um filtro pode fornecer dados esporadicamente. Por exemplo, ele pode analisar um fluxo de dados personalizado e filtrar alguns pacotes enquanto entrega outros. Nesse caso, pode não ser garantido que o filtro forneça dados durante a pausa.
Um filtro de origem (usando o modelo push) ou um filtro de analisador (usando o modelo push/pull) cria um ou mais threads de streaming, que entregam amostras o mais rápido possível. Os filtros a jusante, como descodificadores e transformadores, normalmente enviam dados apenas quando é chamada a função de Receção nos seus pinos de entrada.
Tópicos relacionados