QueryAccept (Downstream)
[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEngine e Audio/Video Capture in 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 in 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.]
Esse mecanismo permite que um pino de saída proponha um novo formato para seu par downstream. O novo formato não deve exigir um tamanho de buffer maior. O pino de saída faz o seguinte:
Chama IPin::QueryAccept ou IPinConnection::D ynamicQueryAccept no pino downstream, para verificar se o outro pin pode aceitar o novo tipo de mídia (consulte ilustração, etapa A).
Se o valor retornado da etapa 1 for S_OK, o pino anexa o tipo de mídia ao próximo exemplo. Para fazer isso, primeiro ele chama IMemAllocator::GetBuffer para obter o exemplo (B). Em seguida, ele chama IMediaSample::SetMediaType para anexar o tipo de mídia a esse exemplo (C). Ao anexar o tipo de mídia ao exemplo, o filtro indica que o formato foi alterado, começando com esse exemplo.
O pino fornece o exemplo (D).
Quando o filtro downstream recebe o exemplo, ele chama IMediaSample::GetMediaType para recuperar o novo tipo de mídia.
Todos os pinos dão suporte ao QueryAccept
método . No entanto, esse método é ligeiramente ambíguo, pois um valor retornado de S_OK nem sempre garante que você possa alterar o formato enquanto o grafo estiver ativo. Alguns filtros podem retornar S_OK mas rejeitar a alteração se o grafo estiver ativo. O método DynamicQueryAccept , que é compatível com alguns pinos de entrada, define explicitamente S_OK para significar que o pino pode alterar formatos enquanto estiver ativo. Se um pin de entrada der suporte à interface IPinConnection , você deverá chamar DynamicQueryAccept em vez de QueryAccept
.
Na maioria dos casos, esse mecanismo não permite alterações drásticas no formato, como alterar a profundidade do bit. Uma situação em que ele pode ser usado é quando um decodificador de vídeo alterna paletas. Os detalhes básicos do formato permanecem os mesmos, como as dimensões da imagem e a profundidade do bit, mas o novo tipo de mídia tem um conjunto diferente de entradas de paleta.
Nota de implementação
Nas classes base do DirectShow, CBasePin::QueryAccept chama o método CheckMediaType , que também é chamado durante a conexão de pino inicial. No caso de um filtro de transformação, o método CheckMediaType do pino de entrada deve sempre marcar se o pino de saída está conectado e, em caso afirmativo, se o tipo de mídia de entrada é compatível com o tipo de mídia de saída. Portanto, essa implementação provavelmente será válida para QueryAccept
. Caso contrário, você deve substituir QueryAccept
para executar quaisquer verificações adicionais necessárias. Além disso, observe que a classe CTransformFilter encapsula essa lógica nos métodos CheckInputType e CheckTransform . A classe CTransInPlaceFilter, por outro lado, sempre chama QueryAccept
no próximo filtro upstream ou downstream.
O método CBaseInputPin::Receive verifica se há um tipo de mídia no exemplo de entrada e, se houver um, chama CheckMediaType. No entanto, ele não atualiza o membro m_mt do pino, que contém o tipo de mídia atual. Quando o filtro processa o exemplo, você deve marcar o exemplo para um tipo de mídia. Se houver um novo tipo, você provavelmente precisará armazená-lo, chamando SetMediaType no pin ou definindo o valor de m_mt diretamente. Por outro lado, a classe CVideoTransformFilter , projetada para filtros de transformação de vídeo, armazena o tipo de mídia quando ela é alterada. Para obter detalhes, consulte o código-fonte para CVideoTransformFilter::Receive na biblioteca de classes base do DirectShow.
Em alguns casos, você pode simplesmente passar a QueryAccept
chamada downstream, anexar o tipo de mídia ao exemplo de saída e permitir que o filtro downstream manipule a alteração de formato.