Relógio de Apresentação
O relógio de apresentação é um objeto que gera a hora do relógio para uma apresentação. A hora relatada pelo relógio de apresentação é chamada de hora da apresentação. Todos os fluxos em uma apresentação são sincronizados com a hora da apresentação. O relógio de apresentação expõe as interfaces a seguir.
Os coletores de mídia usam o tempo de apresentação para agendar quando renderizar amostras. Sempre que um coletor de mídia recebe um novo exemplo, ele obtém o carimbo de data/hora da amostra e renderiza a amostra no momento indicado ou o mais próximo possível desse horário. Como todos os coletores de mídia em uma topologia compartilham o mesmo relógio de apresentação, vários fluxos (como áudio e vídeo) são sincronizados. As fontes de mídia e as transformações não usam o relógio de apresentação, pois não agendam quando entregar amostras. Em vez disso, eles produzem amostras sempre que o pipeline solicita uma nova amostra.
Se você estiver usando a Sessão de Mídia para reprodução, a Sessão de Mídia manipulará todos os detalhes da criação do relógio de apresentação, selecionando uma fonte de tempo e notificando os coletores de mídia. Seu aplicativo pode usar o relógio de apresentação para obter o tempo de apresentação atual durante a reprodução, mas, caso contrário, não chamará nenhum método no relógio de apresentação.
Tempo de Relógio e Estados do Relógio
Para obter a hora do relógio mais recente do relógio de apresentação, chame IMFPresentationClock::GetTime. Os horários de relógio estão sempre em unidades de 100 nanossegundos, portanto, um segundo é 10.000.000 (10^7) tiques. Isso corresponde a uma frequência de 10 MHz.
O relógio de apresentação tem três estados: em execução, pausado e parado.
- Para executar o relógio, chame IMFPresentationClock::Start. O método Iniciar especifica a hora de início do relógio. Enquanto o relógio está em execução, o tempo do relógio é incrementado a partir da hora inicial, na taxa de relógio atual.
- Para pausar o relógio, chame IMFPresentationClock::P ause. Enquanto o relógio está em pausa, a hora do relógio não avança, e GetTime retorna a hora em que o relógio foi pausado.
- Para parar o relógio, chame IMFPresentationClock::Stop. Quando o relógio é interrompido, a hora do relógio não avança e GetTime retorna zero.
Por padrão, o relógio avança a uma taxa de 1,0, o que significa 1 tique por 100 nanossegundos. Para alterar a taxa em que o relógio avança, consulte o relógio de apresentação para a interfaceIMFRateControl e chame IMFRateControl::SetRate.
Os objetos podem receber notificações de alterações de estado (incluindo alterações de taxa) do relógio de apresentação. Para receber notificações, implemente a interface deIMFClockStateSink e chame IMFPresentationClock::AddClockStateSink no relógio de apresentação. Antes de desligar, chame IMFPresentationClock::RemoveClockStateSink para cancelar o registro do objeto. Os coletores de mídia usam esse mecanismo para receber notificações do relógio.
Tempos de Apresentação
Um coletor de mídia tenta agendar cada exemplo para que o exemplo seja renderizado no momento correto ou o mais próximo possível da hora correta. As seguintes definições se aplicam:
- Hora da apresentação. A hora em que um exemplo deve ser renderizado. O tempo é dado em unidades de 100 nanossegundos.
- Tempo de mídia. Tempo relativo ao início do conteúdo. Por exemplo, se um arquivo de vídeo tiver 10 segundos de duração, o ponto no meio do arquivo terá um tempo de mídia de 5 segundos.
- Carimbo de data/hora. O tempo marcado em um exemplo de mídia. Para obter o carimbo de data/hora, chame IMFSample::GetSampleTime. Quando uma fonte de mídia produz um exemplo, ela define o carimbo de data/hora igual ao tempo de mídia. A Sessão de Mídia converte o carimbo de data/hora na hora da apresentação.
Por padrão, o tempo de mídia e o tempo de apresentação são os mesmos, por exemplo, se um quadro de vídeo aparecer 5 segundos no arquivo de origem, o tempo de mídia e o tempo de apresentação serão ambos de 5 segundos. Se você estiver usando o de Origem do Sequencer, o modelo de tempo será um pouco mais complicado para habilitar transições suaves entre segmentos. Para obter mais informações sobre o modelo de tempo da fonte do sequenciador, consulte Sequence Presentation Times.
A fonte de mídia sempre define o carimbo de data/hora igual ao tempo de mídia. Se a hora da apresentação não estiver alinhada com o tempo de mídia, a Sessão de Mídia converterá os carimbos de data/hora nos exemplos de mídia. Quando o coletor recebe um exemplo, o carimbo de data/hora do exemplo foi convertido em hora de apresentação. O coletor agenda o exemplo na hora atual do relógio de apresentação. (Coletores sem taxa são uma exceção, pois ignoram o relógio de apresentação.)
Se o aplicativo buscar uma nova posição, a Sessão de Mídia reiniciará o relógio de apresentação no horário de busca especificado. Por exemplo, se o aplicativo busca a posição de 5 segundos no arquivo, a Sessão de Mídia inicia o relógio em 5 segundos. A fonte de mídia poderá fornecer amostras com um carimbo de data/hora ligeiramente anterior se o tempo de busca não cair em um limite de quadro-chave. Isso é necessário para que os decodificadores possam decodificar todos os quadros. A Sessão de Mídia descarta ou corta amostras antes que elas cheguem aos coletores de mídia, a fim de corresponder ao tempo de busca solicitado. Por exemplo, se o tempo de busca for de 5 segundos, o primeiro exemplo de áudio poderá começar em 4,5 segundos. A Sessão de Mídia cortará os primeiros 0,5 segundos da primeira amostra de áudio decodificada.
Criando o relógio de apresentação
Para criar o relógio de apresentação, chame MFCreatePresentationClock. Para desligar o relógio, consulte a interface deIMFShutdown e chame IMFShutdown::Shutdown. O chamador do MFCreatePresentationClock do é responsável por chamar desligamento; na maioria dos casos, essa é a Sessão de Mídia em vez do aplicativo.
Fontes de tempo de apresentação
Apesar do nome, o relógio de apresentação não implementa um relógio. Em vez disso, ele obtém os horários do relógio de outro objeto, chamado de de origem do horário da apresentação. A fonte de tempo pode ser qualquer objeto que gere tiques de relógio precisos e exponha a interfaceIMFPresentationTimeSource. A ilustração a seguir mostra esse processo.
Quando o relógio de apresentação é criado pela primeira vez, ele não tem uma fonte de tempo. Para definir a fonte de tempo, chame imfPresentationClock::SetTimeSource com um ponteiro para a interface deIMFPresentationTimeSource da fonte de tempo. Uma fonte de tempo dá suporte aos mesmos estados que o relógio de apresentação (em execução, pausada e parada) e deve implementar a interfaceIMFClockStateSink. O relógio de apresentação usa essa interface para notificar a fonte de tempo quando alterar o estado. Dessa forma, a fonte de tempo fornece tiques de relógio, mas o relógio de apresentação inicia alterações de estado no relógio.
Alguns coletores de mídia têm acesso a um relógio preciso e, portanto, expõem a interfaceIMFPresentationTimeSource. Em particular, o renderizador de áudio pode usar a frequência da placa de som como relógio. Na reprodução de áudio, é útil que o renderizador de áudio atue como a fonte de tempo, para que o vídeo seja sincronizado com a taxa de reprodução de áudio. Isso geralmente produz resultados melhores do que tentar corresponder o áudio a um relógio externo.
O Media Foundation também fornece uma fonte de tempo de apresentação com base no relógio do sistema. Para criar esse objeto, chame MFCreateSystemTimeSource. A fonte de tempo do sistema pode ser usada quando nenhum coletor de mídia fornece uma fonte de tempo.
Em geral, um coletor de mídia deve usar o relógio de apresentação fornecido a ele, independentemente de qual fonte de tempo o relógio de apresentação usa. Essa regra se aplica mesmo quando um coletor de mídia implementa IMFPresentationTimeSource. Se o relógio de apresentação usar outra fonte de tempo, o coletor de mídia deverá seguir essa fonte de tempo, não seu próprio relógio interno.
Há duas situações em que um coletor de mídia não seguirá o relógio da apresentação:
Alguns coletores de mídia são sem taxa . Se um coletor de mídia estiver sem taxa, ele consumirá amostras o mais rápido possível, sem agendá-los de acordo com o relógio de apresentação. Normalmente, coletores sem taxa gravam dados em um arquivo, portanto, é desejável concluir a operação o mais rápido possível. Um coletor sem taxa retorna a bandeira MEDIASINK_RATELESS em seu método IMFMediaSink::GetCharacteristics. Quando todos os coletores em uma topologia são sem taxa, a Sessão de Mídia envia dados por push pelo pipeline o mais rápido possível.
Alguns coletores de mídia não podem corresponder taxas com uma fonte de tempo diferente de si mesmos. Nesse caso, o coletor retorna o sinalizador MEDIASINK_CANNOT_MATCH_CLOCK em seu métodogetcharacteristics. O pipeline ainda pode usar outra fonte de tempo, mas os resultados serão menores que o ideal. O coletor provavelmente ficará para trás e causará falhas durante a reprodução.
Tópicos relacionados
-
APIs do Media Foundation Platform