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 o horário da apresentação. O relógio de apresentação expõe as interfaces a seguir.
Interface | Descrição |
---|---|
IMFPresentationClock | Interface primária para usar o relógio de apresentação. |
IMFRateControl | Controla a taxa de relógio. |
IMFTimer | Fornece um retorno de chamada do temporizador. |
IMFShutdown | Desliga o relógio da apresentação. |
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 o exemplo 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 um novo exemplo.
Se você estiver usando a Sessão de Mídia para reprodução, a Sessão de Mídia lidará com 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.
Estados de Relógio e Hora do Relógio
Para obter a hora do relógio mais recente do relógio de apresentação, chame IMFPresentationClock::GetTime. Os tempos 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 interrompido.
- Para executar o relógio, chame IMFPresentationClock::Start. O método Start especifica a hora de início do relógio. Enquanto o relógio está em execução, o tempo do relógio incrementa a partir da hora de início, 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 na qual o relógio avança, consulte o relógio de apresentação para a interface IMFRateControl 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 IMFClockStateSink 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 em 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 de cinco segundos. Se você estiver usando a 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 origem do sequenciador, consulte Tempos de apresentação de sequência.
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. No momento em que o coletor recebe uma amostra, o carimbo de data/hora da amostra foi convertido em hora da 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 buscar a posição de 5 segundos no arquivo, a Sessão de Mídia iniciará 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 do primeiro exemplo de áudio decodificado.
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 IMFShutdown e chame IMFShutdown::Shutdown. O chamador de MFCreatePresentationClock é 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 fonte de tempo de apresentação. A fonte de tempo pode ser qualquer objeto que gere tiques de relógio precisos e exponha a interface IMFPresentationTimeSource . A ilustração a seguir mostra este 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 IMFPresentationTimeSource 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 interface IMFClockStateSink . 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 interface IMFPresentationTimeSource . Em particular, o renderizador de áudio pode usar a frequência do som cartão como um 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 melhores resultados 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 alguma 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 segue o relógio de apresentação:
Alguns coletores de mídia são sem taxas. Se um coletor de mídia for sem taxa, ele consumirá amostras o mais rápido possível, sem agendá-las 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 rateless, 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 a taxas com uma fonte de tempo diferente de si mesmos. Nesse caso, o coletor retorna o sinalizador MEDIASINK_CANNOT_MATCH_CLOCK em seu método GetCharacteristics . O pipeline ainda pode usar outra fonte de tempo, mas os resultados serão menores do que o ideal. O coletor provavelmente ficará para trás e causará falhas durante a reprodução.
Tópicos relacionados