Partilhar via


Dissipadores de mídia

Coletores de mídia são os objetos de pipeline que recebem dados de mídia. Um coletor de mídia é o destino de um ou mais fluxos de mídia. Os dissipadores de mídia se enquadram em duas categorias gerais:

  • Um renderizador é um coletor de mídia que apresenta dados para reprodução. O renderizador de vídeo aprimorado (EVR) exibe quadros de vídeo e o renderizador de áudio reproduz fluxos de áudio através da placa de som ou outro dispositivo de áudio.

  • Um coletor de arquivo é um coletor de mídia que grava dados em um arquivo ou outro armazenamento.

A principal diferença entre eles é que um coletor de arquivo não consome os dados a uma taxa de reprodução fixa. Em vez disso, grava os dados que recebe o mais rapidamente possível.

Os coletores de mídia expõem a interfaceIMFMediaSink. Cada coletor de mídia contém um ou mais coletores de fluxo. Cada coletor de fluxo recebe os dados de um fluxo. Os coletores de fluxo expõem a interfaceIMFStreamSink. Normalmente, um aplicativo não cria coletores de mídia diretamente. Em vez disso, o aplicativo cria um ou mais objetos de ativação, que a sessão de mídia usa para criar o coletor. Todas as outras operações no coletor são tratadas pela Sessão de Mídia, e o aplicativo não chama nenhum método no coletor de mídia ou em qualquer um dos coletores de fluxo. Para obter mais informações sobre objetos de ativação, consulte Activation Objects.

Você deve ler o restante deste tópico se estiver escrevendo um coletor de mídia personalizado ou se quiser usar um coletor de mídia diretamente sem a Sessão de mídia.

Sumidouros de fluxo

Um coletor de mídia pode ter um número fixo de coletores de fluxo ou pode suportar a adição e remoção de coletores de fluxo. Se tiver um número fixo de coletores de fluxo, o métodoIMFMediaSink::GetCharacteristicsretornará o sinalizador MEDIASINK_FIXED_STREAMS. Caso contrário, você pode adicionar e remover coletores de fluxo. Para adicionar um novo coletor de fluxo, chame IMFMediaSink::AddStreamSink. Para remover um coletor de fluxo, chame IMFMediaSink::RemoveStreamSink. O sinalizador MEDIASINK_FIXED_STREAMS indica que o coletor de mídia não suporta esses dois métodos. (Ele pode oferecer suporte a alguma outra maneira de configurar o número de fluxos, por exemplo, definindo parâmetros de inicialização quando o coletor é criado.) A lista de coletores de fluxo é ordenada. Para enumerá-los por valor de índice, chame o IMFMediaSink::GetStreamSinkByIndex método.

Os coletores de fluxo também têm identificadores. Os identificadores de fluxo são exclusivos dentro do coletor de mídia, mas não precisam ser consecutivos. Dependendo do coletor de mídia, os identificadores de fluxo podem ter algum significado relacionado ao conteúdo. Por exemplo, um coletor de arquivo morto pode gravar os identificadores de fluxo no cabeçalho do arquivo. Caso contrário, são arbitrárias. Para obter um coletor de fluxo por seu identificador, chame IMFMediaSink::GetStreamSinkById.

Relógio de Apresentação

A taxa na qual um coletor de mídia consome amostras é controlada pelo Presentation Clock. A Sessão de Mídia seleciona o relógio de apresentação e o define no coletor de mídia chamando o do coletor de mídia IMFMediaSink::SetPresentationClock método. O relógio de apresentação deve ser ajustado no coletor de mídia antes que o streaming possa começar. Cada dissipador de mídia requer um relógio de apresentação para ser executado. O dissipador de mídia usa o relógio de apresentação para duas finalidades:

  • Para receber notificações quando o streaming é iniciado ou interrompido. O coletor de mídia recebe essas notificações por meio da interface deIMFClockStateSink, que todos os coletores de mídia devem implementar.

  • Para determinar quando ele deve renderizar amostras. Quando o coletor de mídia recebe uma nova amostra, ele obtém o carimbo de data/hora da amostra e tenta renderizar a amostra naquele momento da apresentação.

O relógio de apresentação deriva seus tempos de relógio de outro objeto chamado fonte de tempo de apresentação. As fontes de tempo de apresentação expõem a interfaceIMFPresentationTimeSource. Alguns coletores de mídia têm acesso a um relógio preciso, por isso expõem essa interface. Isso significa que um coletor de mídia pode agendar amostras em relação a um tempo fornecido por seu próprio relógio. No entanto, os meios de comunicação social não podem presumir que seja esse o caso. Ele deve sempre usar o tempo do relógio de apresentação, independentemente de o relógio de apresentação ser acionado pelo próprio coletor de mídia ou por algum outro relógio.

Se um coletor de mídia não puder corresponder taxas com um relógio diferente do seu, o métodoGetCharacteristicsretornará o sinalizador MEDIASINK_CANNOT_MATCH_CLOCK. Se esse sinalizador estiver presente e o relógio de apresentação usar uma fonte de tempo de apresentação diferente, é provável que o coletor de mídia tenha um desempenho insatisfatório. Por exemplo, pode falhar durante a reprodução.

Um coletor de sem taxa é um coletor de mídia que ignora os carimbos de data/hora nas amostras e consome dados assim que cada amostra chega. Um coletor de mídia sem taxa retorna o sinalizador de MEDIASINK_RATELESS do GetCharacteristics método. Normalmente, esse sinalizador se aplica a coletores de arquivo. Se cada coletor de mídia no pipeline for sem taxa, a Sessão de mídia usará um relógio de apresentação sem taxa especial. Este relógio funciona tão rapidamente quanto os lavatórios consomem amostras.

Formatos de fluxo

Antes que o coletor de mídia possa receber amostras, o cliente deve definir o tipo de mídia nos coletores de fluxo. Para definir o tipo de mídia, chame o do coletor de fluxo IMFStreamSink::GetMediaTypeHandler método. Esse método retorna um ponteiro para o IMFMediaTypeHandler interface. Use essa interface para obter a lista de tipos de mídia preferidos, obter o tipo de mídia atual e definir o tipo de mídia.

Para obter a lista de tipos de mídia preferidos, ligue IMFMediaTypeHandler::GetMediaTypeByIndex. Os tipos preferidos devem ser tomados como uma dica para o cliente. A lista pode estar incompleta ou incluir tipos de mídia parciais. Um tipo de mídia parcial é aquele que não tem todos os atributos necessários para descrever um formato válido. Por exemplo, um tipo de vídeo parcial pode especificar o espaço de cor e a profundidade de bits, mas não a largura ou a altura da imagem. Um tipo de áudio parcial pode especificar o formato de compressão e a taxa de amostragem, mas não o número de canais de áudio.

Para obter o tipo de mídia atual do coletor de fluxo, chame IMFMediaTypeHandler::GetCurrentMediaType. Quando um coletor de fluxo é criado pela primeira vez, ele pode ter um tipo de mídia padrão já definido ou pode não ter nenhum tipo de mídia até que o cliente defina um.

Para definir o tipo de mídia, chame IMFMediaTypeHandler::SetCurrentMediaType. Alguns coletores de fluxo podem não suportar a alteração do tipo depois de ter sido definido. Portanto, é útil testar os tipos de mídia antes de defini-los. Para testar se o coletor de mídia aceitará um tipo de mídia (sem definir o tipo), chame IMFMediaTypeHandler::IsMediaTypeSupported.

Fluxo de dados

Os coletores de mídia usam um modelo de pull, o que significa que os coletores de fluxo solicitam dados conforme necessário. O cliente deve responder atempadamente para evitar qualquer encandeamento.

Alguns dissipadores de mídia suportam pré-rolagem. A pré-rolagem é o processo de fornecer dados para o coletor de mídia antes do relógio de apresentação começar. Se um coletor de mídia oferecer suporte à pré-rolagem, o coletor de mídia expõe o interface de IMFMediaSinkPreroll e o método GetCharacteristics retornará o sinalizador MEDIASINK_CAN_PREROLL. A pré-rolagem garante que o coletor de mídia esteja pronto para apresentar a primeira amostra quando o relógio de apresentação for iniciado. Recomenda-se que o cliente sempre pré-role se o coletor de mídia suportar, porque pode evitar glitching ou lacunas durante a reprodução.

O fluxo de dados para um coletor de mídia funciona da seguinte maneira:

  1. O cliente define os tipos de mídia e o relógio de apresentação. O coletor de mídia se registra com o relógio de apresentação para receber notificações sobre alterações no estado do relógio.
  2. Opcionalmente, o cliente consulta IMFMediaSinkPreroll. Se o coletor de mídia expõe essa interface, o cliente chama IMFMediaSinkPreroll::NotifyPreroll. Caso contrário, o cliente pula para a etapa 5.
  3. Cada coletor de fluxo envia um ou mais eventos de MEStreamSinkRequestSample. Em resposta a cada um desses eventos, o cliente obtém a próxima amostra de dados para esse fluxo e chama IMFStreamSink::P rocessSample.
  4. Quando cada coletor de fluxo recebe dados de pré-rolagem suficientes, ele envia um evento de MEStreamSinkPrerolled.
  5. O cliente chama IMFPresentationClock::Start para iniciar o relógio de apresentação.
  6. O relógio de apresentação notifica o coletor de mídia de que o relógio está iniciando, chamando IMFClockStateSink::OnClockStart.
  7. Para obter mais dados, cada coletor de fluxo envia eventos de MEStreamSinkRequestSample. Em resposta a cada um desses eventos, o cliente obtém o próximo exemplo e chama ProcessSample. Esta etapa é repetida até que a apresentação termine.

A maioria dos coletores de mídia processa amostras de forma assíncrona, de modo que os coletores de fluxo podem enviar mais de uma solicitação de amostra de cada vez.

Durante o streaming, o cliente pode ligar IMFStreamSink::P laceMarker e IMFStreamSink::Flush a qualquer momento. Os marcadores são descritos na próxima seção. A descarga faz com que o coletor de fluxo solte todas as amostras que ele enfileirou, mas ainda não renderizou.

Marcadores

Os marcadores fornecem uma maneira para o cliente indicar pontos específicos no fluxo. Um marcador consiste nas seguintes informações:

  • O tipo de marcador, definido como um membro da enumeração MFSTREAMSINK_MARKER_TYPE.
  • Dados associados ao marcador. O significado dos dados depende do tipo de marcador. Alguns tipos de marcadores não têm dados.
  • Dados opcionais para uso próprio do cliente.

Para colocar um marcador, o cliente chama IMFStreamSink::P laceMarker. O coletor de fluxo conclui o processamento de todas as amostras recebidas antes da chamada de PlaceMarker do e, em seguida, envia um evento MEStreamSinkMarker.

A maioria dos coletores de mídia mantém uma fila de amostras pendentes, que são processadas de forma assíncrona. Os eventos de marcador devem ser serializados com processamento de amostra, portanto, o coletor de mídia deve colocar os marcadores na mesma fila. Por exemplo, suponha que o cliente faça as seguintes chamadas de método:

  1. ProcessSample (Amostra #1)
  2. ProcessSample (Amostra #2)
  3. PlaceMarker (Marcador #1)
  4. ProcessSample (Amostra #3)
  5. PlaceMarker (Marcador #2)

Neste exemplo, o coletor de fluxo deve enviar o evento MEStreamSinkMarker para o marcador #1 depois de processar a amostra #2 e o evento para o marcador #2 depois de processar a amostra #3.

Se o cliente liberar um coletor de fluxo, o coletor de fluxo processará imediatamente todos os marcadores que estavam na fila. Ele define o código de status para E_ABORT nesses eventos.

Alguns marcadores contêm informações que são relevantes para o coletor de mídia:

  • MFSTREAMSINK_MARKER_TICK: Indica que há uma lacuna no fluxo. A próxima amostra será uma descontinuidade.
  • MFSTREAMSINK_MARKER_ENDOFSEGMENT: Indica o fim de um segmento ou o fim de um fluxo. A próxima amostra (se houver) pode ser uma descontinuidade.
  • MFSTREAMSINK_MARKER_EVENT: Contém um evento. Dependendo do tipo de evento e da implementação do coletor de mídia, o coletor de mídia pode manipular o evento ou ignorá-lo.

Alterações de Estado

Um coletor de mídia é notificado de alterações de estado no relógio de apresentação por meio da interface deIMFClockStateSink do coletor de mídia. Quando o cliente define o relógio de apresentação, o coletor de mídia chama IMFPresentationClock::AddClockStateSink para se registrar para notificações do relógio. A tabela a seguir resume como um coletor de mídia se comporta em resposta a alterações de estado de relógio.

Alteração do estado do relógio Processamento de amostras Processamento de marcadores
OnClockStart Processar amostras cujo carimbo de data/hora seja igual ou posterior à hora de início do relógio. Envie o evento MEStreamSinkMarker quando todas as amostras recebidas antes do marcador tiverem sido processadas.
OnClockPause O coletor de mídia pode falhar ProcessSample durante a pausa.
Se o coletor de mídia aceitar amostras durante a pausa, ele deverá enfileirá-las até que o relógio seja reiniciado. Não processe amostras em fila durante a pausa.
Se houver amostras enfileiradas, coloque marcadores na mesma fila. Envie o evento de marcador quando o relógio for reiniciado.
Caso contrário, envie o evento de marcador imediatamente.
OnClockRestart Processe todas as amostras que foram enfileiradas durante a pausa e, em seguida, trate o mesmo que OnClockStart. Envie eventos de MEStreamSinkMarker para marcadores em fila (serializados com processamento de amostra) e, em seguida, trate o mesmo que OnClockStart.
OnClockStop Solte todas as amostras enfileiradas. Outras chamadas para ProcessSample podem falhar. Enviar eventos de marcador em fila. Em chamadas subsequentes para PlaceMarker, envie o evento de marcador imediatamente.

 

Além disso, os coletores de fluxo devem enviar os seguintes eventos quando tiverem concluído as transições de estado:

Finalização

Alguns coletores de mídia exigem uma etapa de processamento extra após a última amostra ser entregue. Normalmente, esse requisito se aplica a coletores de arquivamento, que devem gravar cabeçalhos ou índices no arquivo. Se um coletor de mídia exigir qualquer processamento final, ele expõe a interfaceIMFFinalizableMediaSink.

Depois que o cliente entrega a última amostra, o cliente consulta essa interface. Se o coletor de mídia suportar a interface, o cliente chamará IMFFinalizableMediaSink::BeginFinalize para executar o processamento final de forma assíncrona. Esse método segue o modelo assíncrono padrão do Media Foundation, descrito em Asynchronous Callback Methods. O coletor de mídia pode presumir que o cliente chamará BeginFinalize. A falha ao chamar BeginFinalize pode resultar em um arquivo criado incorretamente.

Desligamento

Quando o cliente termina de usar o coletor de mídia, o cliente chama IMFMediaSink::Shutdown. Dentro deste método, o coletor de mídia deve quebrar qualquer contagem de referência circular. Normalmente, haverá referências circulares entre o coletor de mídia e os coletores de fluxo.

Se você estiver usando o objeto auxiliar da fila de eventos para implementar IMFMediaEventGenerator, chame IMFMediaEventQueue::Shutdown na fila de eventos. Esse método desliga a fila de eventos e sinaliza qualquer chamador que esteja aguardando um evento no momento.

Após o desligamento, todos os métodos no coletor de mídia retornam MF_E_SHUTDOWN, com exceção de métodos IUnknown.

Interfaces de coletor de mídia

A tabela a seguir lista as interfaces padrão que os coletores de mídia podem expor por meio QueryInterface. Os coletores de mídia também podem expor interfaces personalizadas.

Interface Descrição
IMFMediaSink A interface principal para coletores de mídia. (Obrigatório.)
IMFClockStateSink Usado para notificar o coletor de mídia quando o relógio de apresentação muda de estado. (Obrigatório.)
IMFFinalizableMediaSink Implemente se o coletor de mídia precisar executar uma etapa de processamento final. (Opcional.)
IMFGetService Implemente se o coletor de mídia expõe quaisquer interfaces de serviço. (Opcional.)
IMFMediaEventGenerator Implemente se o coletor de mídia enviar algum evento. (Opcional.)
IMFMediaSinkPreroll Implemente se o coletor de mídia suportar preroll. (Opcional.)
IMFPresentationTimeSource Implemente se o coletor de mídia puder fornecer uma fonte de tempo para o relógio de apresentação. (Opcional.)
IMFQualityAdvise Implemente se o coletor de mídia puder ajustar a qualidade de reprodução. (Opcional.)

 

Opcionalmente, um coletor de mídia pode implementar a seguinte interface como um serviço.

Interface de serviço Descrição
IMFRateSupport Informa a gama de taxas de reprodução suportadas.

 

Para obter mais informações sobre interfaces de serviço e IMFGetService, consulte Service Interfaces.

Interfaces de coletor de fluxo

Os coletores de fluxo devem expor as seguintes interfaces por meio QueryInterface.

Interface Descrição
IMFStreamSink A interface principal para coletores de fluxo. (Obrigatório.)
IMFMediaEventGenerator Eventos de filas. A interface IMFStreamSink herda essa interface. (Obrigatório.)

 

Atualmente, nenhuma interface de serviço é definida para coletores de fluxo.

Stream Sink Eventos

A tabela a seguir lista os eventos definidos para coletores de fluxo genéricos. Os coletores de fluxo também podem enviar eventos personalizados não listados aqui.

Evento Descrição
MEStreamSinkFormatChanged O tipo de mídia do coletor de fluxo não é mais válido. (Opcional.)
MEStreamSinkMarker Um marcador foi processado. (Obrigatório.)
MEStreamSinkPaused O dissipador do fluxo parou. (Obrigatório.)
MEStreamSinkPrerolled O preroll está completo. (Opcional.)
MEStreamSinkRateChanged O coletor de fluxo mudou a taxa de reprodução. (Opcional.)
MEStreamSinkRequestSample Uma nova amostra é solicitada. (Obrigatório.)
MEStreamSinkScrubSampleComplete Um pedido de limpeza foi concluído. (Opcional.)
MEStreamSinkStarted O sumidouro do córrego já começou. (Obrigatório.)
MEStreamSinkStopped O sumidouro do córrego parou. (Obrigatório.)

 

Atualmente, nenhum evento de uso geral é definido para dissipadores de mídia. Alguns coletores de mídia podem enviar eventos personalizados.

Media Foundation Pipeline

de arquitetura da Media Foundation