Processando dados em um DMO
[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.]
Esta seção explica como processar um fluxo de dados usando um DMO. As etapas listadas nesta seção são o comportamento padrão; todos os DMOs devem dar suporte aos métodos descritos aqui. Esses métodos usam buffers separados para entrada e saída. Alguns DMOs também dão suporte ao processamento in-loco, usando um único buffer. Para obter mais informações sobre o processamento in-loco, consulte Processamento in-loco.
Alocando buffers
O cliente é responsável por toda a alocação de buffer. Depois de definir os tipos de mídia no DMO, consulte o DMO para os requisitos de buffer de cada fluxo. Elas podem ser alteradas dependendo do tipo de mídia. Para cada fluxo, chame o método IMediaObject::GetInputSizeInfo ou IMediaObject::GetOutputSizeInfo . Esses métodos retornam as seguintes informações:
- Tamanho mínimo do buffer, em bytes.
- Requisitos de alinhamento, se houver. Um buffer será alinhado se o endereço inicial for um múltiplo de algum inteiro especificado.
- A quantidade máxima de dados que o DMO conterá para lookahead. Esse número se aplica somente a fluxos de entrada. Para alguns tipos de dados (por exemplo, codificação MPEG), um DMO pode precisar olhar para frente no fluxo. O valor lookahead indica a quantidade de dados de entrada que o DMO exigirá antes que ele possa produzir a saída.
O cliente deve alocar buffers que correspondam a esses requisitos. Além disso, o DMO pode ter requisitos sobre como o cliente empacota os dados de entrada. Por exemplo, o DMO pode exigir que cada buffer contenha exatamente um exemplo (ou quadro de vídeo). Para determinar esses requisitos, chame o método IMediaObject::GetInputStreamInfo . O método IMediaObject::GetOutputStreamInfo retorna informações semelhantes sobre um fluxo de saída.
No modelo de streaming padrão, o cliente não passa ponteiros de buffer brutos para o DMO. Em vez disso, ele usa um objeto COM leve que expõe a interface IMediaBuffer . A interface IMediaBuffer atua como um wrapper COM para um bloco de memória. Como ele é um objeto COM, ele dá suporte à contagem de referência, o que ajuda a garantir que os buffers não sejam liberados enquanto ainda estiverem em uso.
Observação
A interface IMediaBuffer serve a uma função semelhante à interface IMediaSample no DirectShow.
O cliente deve implementar o objeto IMediaBuffer . Para obter mais informações, consulte Implementando o IMediaBuffer.
Processando os dados
Para processar dados, faça o seguinte:
- Para cada fluxo de entrada, preencha um buffer com dados de entrada.
- Chame IMediaObject::P rocessInput para entregar cada buffer.
- Chame IMediaObject::P rocessOutput para processar os dados. Esse método usa uma matriz de buffers, uma para cada fluxo de saída.
- Repita até que não haja mais dados de entrada.
O método ProcessInput aceita entrada para um fluxo por vez. Normalmente, o método retorna imediatamente e o DMO mantém uma contagem de referência no objeto IMediaBuffer . Ele libera o objeto depois de processar todos os dados no buffer ou quando o aplicativo libera o DMO. Não use novamente um buffer até que o DMO o libere. Para determinar se um fluxo de entrada pode aceitar mais dados, chame o método IMediaObject::GetInputStatus . Esse método retornará o sinalizador DMO_INPUT_STATUSF_ACCEPT_DATA se o fluxo puder aceitar mais entradas.
O método ProcessOutput gera saída para todos os fluxos de saída de uma só vez. O aplicativo passa uma matriz de estruturas de DMO_OUTPUT_DATA_BUFFER , uma para cada fluxo de saída. Cada estrutura na matriz tem um ponteiro para um objeto IMediaBuffer . O DMO grava o máximo de dados de saída possível nos buffers. Ele também define vários sinalizadores para relatar o status da operação. O sinalizador DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE indica que o DMO pode produzir mais saída da entrada existente. Nesse caso, o cliente pode chamar ProcessOutput novamente. Caso contrário, ele deve chamar ProcessInput com mais dados de entrada. O DMO nunca modifica os dados nos buffers de entrada; ele grava somente nos buffers de saída.
Depois de entregar todos os dados a um fluxo de entrada, chame o método IMediaObject::D iscontinuity . O DMO não aceita mais entradas nesse fluxo até que você processe a saída restante (ou libere o DMO).
A qualquer momento após o início do streaming, o DMO é capaz de receber entrada ou produzir saída, ou ambos. Portanto, GetInputStatus retorna DMO_INPUT_STATUSF_ACCEPT_DATA ou ProcessOutput retorna DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE. O aplicativo mantém os dados fluindo testando esses sinalizadores e chamando ProcessInput ou ProcessOutput adequadamente. Para interromper o fluxo de dados, chame o método IMediaObject::Flush . Esse método faz com que o DMO descarte todos os buffers que está mantendo internamente.
Tópicos relacionados