Como usar a origem do sequenciador
Este tópico descreve como usar a Origem do Sequenciador. Ele contém as seções a seguir:
- Visão geral
- Como adicionar topologias
- Como excluir topologias
- Como ignorar um segmento
- Tópicos relacionados
Para obter uma visão geral da origem do sequenciador, confira Sobre a origem do sequenciador.
Visão geral
A origem do sequenciador expõe as interfaces a seguir.
Interface | Descrição |
---|---|
IMFMediaSource | Expõe a funcionalidade de fonte de mídia genérica. |
IMFSequencerSource | Permite que o aplicativo adicione ou remova topologias. |
IMFMediaSourceTopologyProvider | Recupera a próxima topologia a ser enfileirada na Sessão de Mídia. |
IMFMediaSourcePresentationProvider | Usado pela Sessão de Mídia para segmentos finais. Os aplicativos não usam essa interface. |
IMFGetService | Consulta a origem do sequenciador para Interfaces de Serviço. |
Para reproduzir uma sequência de origens de mídia, execute as seguintes etapas:
- Para criar a origem do sequenciador, chame a função MFCreateSequencerSource.
- Para cada segmento, crie uma topologia de reprodução, conforme descrito em Como criar topologias de reprodução. Para adicionar a topologia à apresentação, chame IMFSequencerSource::AppendTopology.
- Antes de iniciar a reprodução, chame IMFMediaSource::CreatePresentationDescriptor na origem do sequenciador. Esse método retorna um ponteiro para um descritor de apresentação do primeiro segmento. Para obter a topologia associada a esse segmento, chame QueryInterface na origem do sequenciador da interface IMFMediaSourceTopologyProvider. Passe o descritor de apresentação para o método IMFMediaSourceTopologyProvider::GetMediaSourceTopology. Esse método retorna um ponteiro para a topologia.
- Passe a topologia do primeiro segmento para a Sessão de Mídia, chamando o método IMFMediaSession::SetTopology da Sessão de Mídia.
- Inicie a reprodução chamando IMFMediaSession::Start.
- Quando a origem do sequenciador está pronta para executar pré-rolagem do próximo segmento, ela envia um evento MENewPresentation cujos dados de evento são um ponteiro de interface IMFPresentationDescriptor. Novamente, obtenha a topologia do segmento chamando GetMediaSourceTopology na origem do sequenciador e defina a topologia na Sessão de Mídia chamando SetTopology. Não é necessário reiniciar a fonte de mídia. Ela será reproduzida automaticamente para o próximo segmento.
- Antes que o aplicativo seja encerrado, desligue a origem do sequenciador chamando IMFMediaSource::Shutdown.
O código a seguir mostra como obter a topologia e defini-la na Sessão de Mídia:
// Queues the next topology on the session.
HRESULT CPlaylist::QueueNextSegment(IMFPresentationDescriptor *pPD)
{
IMFMediaSourceTopologyProvider *pTopoProvider = NULL;
IMFTopology *pTopology = NULL;
//Get the topology for the presentation descriptor
HRESULT hr = m_pSequencerSource->QueryInterface(IID_PPV_ARGS(&pTopoProvider));
if (FAILED(hr))
{
goto done;
}
hr = pTopoProvider->GetMediaSourceTopology(pPD, &pTopology);
if (FAILED(hr))
{
goto done;
}
//Set the topology on the media session
m_pSession->SetTopology(NULL, pTopology);
done:
SafeRelease(&pTopoProvider);
SafeRelease(&pTopology);
return hr;
}
Para obter um exemplo de código completo, confira Código de exemplo da Origem do Sequencer.
Como adicionar topologias
A origem do sequenciador mantém duas listas de topologias: a lista de entrada e a lista de pré-rolagem.
A lista de entrada é uma coleção de topologias correspondentes aos segmentos de playlist, na ordem em que foram adicionados pelo aplicativo chamando IMFSequencerSource::AppendTopology. Esse método atribui a cada topologia um identificador de segmento exclusivo do tipo MFSequencerElementId. O identificador de segmento é definido como um atributo para todos os nós da topologia de origem. Um aplicativo pode obter o identificador de segmento de um nó de origem usando o atributo MF_TOPONODE_SEQUENCE_ELEMENTID. A lista de entrada pode ter topologias duplicadas se o aplicativo chamou AppendTopology na mesma topologia mais de uma vez. No entanto, elas são distinguidas por seus identificadores de segmento exclusivos.
A lista de pré-rolagem é uma coleção de topologias de lista de entrada que foram inicializadas em preparação para reprodução. Isso permite que a Sessão de Mídia faça uma transição para a próxima topologia sem problemas, quando a topologia ativa terminar. O aplicativo não pode adicionar nem remover as topologias diretamente da lista de pré-rolagem. Isso é gerado pela origem do sequenciador quando uma topologia da lista de entrada é selecionada para reprodução. Isso faz com que a origem do sequenciador adicione a próxima topologia da lista de entrada à lista de pré-rolagem. Depois de fazer isso, a origem do sequenciador gera de forma assíncrona o evento MENewPresentation e passa o descritor de apresentação para a topologia de pré-rolagem como dados de evento. O aplicativo deve escutar esse evento usando a interface IMFMediaEventGenerator da Sessão de Mídia e enfileirar a topologia de pré-rolagem na Sessão de Mídia chamando IMFMediaSession::SetTopology. Isso deve ser feito antes que a Sessão de Mídia conclua a reprodução da topologia ativa. SetTopology informa a Sessão de Mídia sobre a próxima topologia que ela deve reproduzir após o término da reprodução da topologia ativa. Para garantir uma transição sem problemas, o aplicativo deve chamar SetTopology antes que a Sessão de Mídia conclua a reprodução da topologia anterior. Caso contrário, haverá um intervalo entre os segmentos.
O evento MENewPresentation é gerado desde que haja uma topologia após a topologia ativa. Consequentemente, se a lista de entrada contiver apenas uma topologia ou se a topologia ativa for a última na lista de entrada, esse evento não será gerado.
A lista de pré-rolagem é sincronizada com a lista de entrada e atualizada sempre que uma topologia é adicionada ou excluída da lista de entrada.
Como excluir topologias
Para remover uma topologia da origem do sequenciador, um aplicativo deve chamar o método IMFSequencerSource::DeleteTopology e especificar o identificador de segmento.
Antes de chamar DeleteTopology, o aplicativo deve verificar se a Sessão de Mídia não está usando a topologia que o aplicativo deseja excluir. Para fazer isso, as ações a seguir devem ser realizadas antes que o aplicativo chame DeleteTopology:
O evento MESessionTopologyStatus com MF_TOPOSTATUS_ENDED é recebido na topologia para garantir que a Sessão de Mídia conclui a reprodução.
MESessionTopologyStatus com MF_TOPOSTATUS_STARTED_SOURCE é recebido para a próxima topologia para garantir que a Sessão de Mídia começou a reproduzir a próxima topologia, o evento MESessionEnded é recebido para garantir que a Sessão de Mídia seja concluída com a última topologia na origem do sequenciador.
Se o segmento que está sendo excluído for a topologia ativa, a reprodução será interrompida e a origem do sequenciador gerará o evento MEEndOfPresentationSegment. Se a topologia ativa também for a última topologia, o evento MEEndOfPresentation será gerado.
Como ignorar um segmento
Um aplicativo pode ir para um segmento específico na sequência iniciando a Sessão de Mídia com um deslocamento de segmento, da seguinte maneira:
Chame a função MFCreateSequencerSegmentOffset para criar o deslocamento de segmento. Especifique o identificador do segmento no parâmetro dwId. (O identificador foi retornado pelo método IMFSequencerSource::AppendTopology quando você adicionou pela primeira vez a topologia à origem do sequenciador.) O parâmetro hnsOffset especifica um deslocamento de tempo em relação ao início do segmento. A reprodução será iniciada neste momento. Para o parâmetro pvarSegmentOffset, passe o endereço de um PROPVARIANT vazio. Quando a função retorna, esse PROPVARIANT contém o deslocamento de segmento.
Chame o método IMFMediaSession::Start na Sessão de Mídia. Para o parâmetro pguidTimeFormat, use o valor de GUID MF_TIME_FORMAT_SEGMENT_OFFSET. Esse valor indica a busca pelo segmento de deslocamento. Para o parâmetro pvarStartPosition, passe o endereço do PROPVARIANT criado na etapa anterior.
O exemplo de código a seguir mostra como ir para o início de um segmento especificado em uma sequência.
// Skips to the specified segment in the sequencer source
HRESULT CPlaylist::SkipTo(DWORD index)
{
if (index >= m_count)
{
return E_INVALIDARG;
}
MFSequencerElementId ID = m_segments[index].SegmentID;
PROPVARIANT var;
HRESULT hr = MFCreateSequencerSegmentOffset(ID, NULL, &var);
if (SUCCEEDED(hr))
{
hr = m_pSession->Start(&MF_TIME_FORMAT_SEGMENT_OFFSET, &var);
PropVariantClear(&var);
}
return hr;
}
Quando o aplicativo procura entre os segmentos, o aplicativo recebe vários eventos à medida que a origem do sequenciador termina o segmento atual e se prepara para reproduzir o novo segmento. Como esses eventos são recebidos de forma assíncrona, é difícil prever a sequência exata de eventos. Os requisitos são os seguintes:
A origem do sequenciador envia um evento MENewPresentation para o novo segmento para o qual a Sessão de Mídia está indo.
Quando a origem do sequenciador termina o segmento ativo, ela envia o evento MEEndOfPresentationSegment.
A origem do sequenciador cancela a topologia de pré-rolagem. Isso resulta nos seguintes eventos para a topologia cancelada:
- Evento MESessionTopologyStatus com o sinalizador MF_TOPOSTATUS_READY.
- Evento MESessionTopologyStatus com o sinalizador MF_TOPOSTATUS_STARTED_SOURCE.
- Evento MEEndOfPresentationSegment com o atributo MF_EVENT_SOURCE_TOPOLOGY_CANCELED para indicar que a topologia foi cancelada pela origem do sequenciador.
Em seguida, a origem do sequenciador envia eventos para o novo segmento, inclusive vários eventos MESessionTopologyStatus.
Se o novo segmento não for o último da lista, a origem do sequenciador atualizará a lista de pré-rolagem e gerará outro MENewPresentation para a nova topologia de pré-rolagem. Para obter informações sobre as topologias na lista de pré-rolagem, confira Sobre a origem do sequenciador.
Mais detalhes sobre os eventos enviados pela origem do sequenciador podem ser encontrados no tópico Eventos de origem do sequenciador.
Tópicos relacionados