Descritores de apresentação
Uma apresentação é um conjunto de fluxos de mídia relacionados que compartilham um horário comum de apresentação. Por exemplo, uma apresentação pode consistir nos fluxos de áudio e vídeo de um filme. Um descritor de apresentação é um objeto que contém a descrição de uma apresentação específica. Os descritores de apresentação são usados para configurar fontes de mídia e alguns coletores de mídia.
Cada descritor de apresentação contém uma lista de um ou mais descritores de fluxo. Eles descrevem os fluxos na apresentação. Os fluxos podem ser selecionados ou desmarcados. Somente os fluxos selecionados produzem dados. Os fluxos desmarcados não estão ativos e não produzem dados. Cada descritor de fluxo tem um manipulador de tipo de mídia, que é usado para alterar o tipo de mídia do fluxo ou obter o tipo de mídia atual do fluxo. (Para obter mais informações sobre tipos de mídia, consulte Tipos de mídia.)
A tabela a seguir mostra as interfaces primárias que cada um desses objetos expõe.
Objeto | Interface |
---|---|
Descritor de apresentação | IMFPresentationDescriptor |
Descritor de fluxo | IMFStreamDescriptor |
Manipulador de tipo de mídia | IMFMediaTypeHandler |
Apresentações de origem de mídia
Cada fonte de mídia fornece um descritor de apresentação que descreve a configuração padrão para a origem. Na configuração padrão, pelo menos um fluxo é selecionado e cada fluxo selecionado tem um tipo de mídia. Para obter o descritor de apresentação, chame IMFMediaSource::CreatePresentationDescriptor. O método retorna um ponteiro IMFPresentationDescriptor .
Você pode modificar o descritor de apresentação da origem para selecionar um conjunto diferente de fluxos. Não modifique o descritor de apresentação, a menos que a fonte de mídia seja interrompida. As alterações são aplicadas quando você chama IMFMediaSource::Start para iniciar a origem.
Para obter o número de fluxos, chame IMFPresentationDescriptor::GetStreamDescriptorCount. Para obter o descritor de fluxo de um fluxo, chame IMFPresentationDescriptor::GetStreamDescriptorByIndex e passe o índice do fluxo. Os fluxos são indexados a partir de zero. O método GetStreamDescriptorByIndex retorna um ponteiro IMFStreamDescriptor . Ele também retorna um sinalizador booliano que indica se o fluxo está selecionado. Se o fluxo estiver selecionado, a fonte de mídia produzirá dados para esse fluxo. Caso contrário, a origem não produzirá nenhum dado para esse fluxo. Para selecionar um fluxo, chame IMFPresentationDescriptor::SelectStream com o índice do fluxo. Para desmarcar um fluxo, chame IMFPresentationDescriptor::D eselectStream.
O código a seguir mostra como obter o descritor de apresentação de uma fonte de mídia e enumerar os fluxos.
HRESULT hr = S_OK;
DWORD cStreams = 0;
BOOL fSelected = FALSE;
IMFPresentationDescriptor *pPresentation = NULL;
IMFStreamDescriptor *pStreamDesc = NULL;
hr = pSource->CreatePresentationDescriptor(&pPresentation);
if (SUCCEEDED(hr))
{
hr = pPresentation->GetStreamDescriptorCount(&cStreams);
}
if (SUCCEEDED(hr))
{
for (DWORD iStream = 0; iStream < cStreams; iStream++)
{
hr = pPresentation->GetStreamDescriptorByIndex(
iStream, &fSelected, &pStreamDesc);
if (FAILED(hr))
{
break;
}
/* Use the stream descriptor. (Not shown.) */
SAFE_RELEASE(pStreamDesc);
}
}
SAFE_RELEASE(pPresentation);
SAFE_RELEASE(pStreamDesc);
Manipuladores de tipo de mídia
Para alterar o tipo de mídia do fluxo ou obter o tipo de mídia atual do fluxo, use o manipulador de tipo de mídia do descritor de fluxo. Chame IMFStreamDescriptor::GetMediaTypeHandler para obter o manipulador de tipo de mídia. Esse método retorna um ponteiro IMFMediaTypeHandler .
Se você simplesmente quiser saber que tipo de dados há no fluxo, como áudio ou vídeo, chame IMFMediaTypeHandler::GetMajorType. Esse método retorna o GUID para o tipo de mídia principal. Por exemplo, um aplicativo de reprodução normalmente conecta um fluxo de áudio ao renderizador de áudio e um fluxo de vídeo ao renderizador de vídeo. Se você usar a Sessão de Mídia ou o carregador de topologia para criar uma topologia, o GUID do tipo principal poderá ser a única informação de formato de que você precisa.
Se seu aplicativo precisar de informações mais detalhadas sobre o formato atual, chame IMFMediaTypeHandler::GetCurrentMediaType. Esse método retorna um ponteiro para a interface IMFMediaType do tipo de mídia. Use essa interface para obter os detalhes do formato.
O manipulador de tipo de mídia também contém uma lista de tipos de mídia com suporte para o fluxo. Para obter o tamanho da lista, chame IMFMediaTypeHandler::GetMediaTypeCount. Para obter um tipo de mídia da lista, chame IMFMediaTypeHandler::GetMediaTypeByIndex com o índice do tipo de mídia. Os tipos de mídia são retornados na ordem aproximada de preferência. Por exemplo, para formatos de áudio, taxas de exemplo mais altas são preferenciais em relação a taxas de exemplo mais baixas. No entanto, não há uma regra definitiva que rege a ordenação, portanto, você deve tratá-la simplesmente como uma diretriz.
A lista de tipos com suporte pode não conter todos os tipos de mídia possíveis compatíveis com o fluxo. Para testar se há suporte para um tipo de mídia específico, chame IMFMediaTypeHandler::IsMediaTypeSupported. Para definir o tipo de mídia, chame IMFMediaTypeHandler::SetCurrentMediaType. Se o método for bem-sucedido, o fluxo conterá dados que estão em conformidade com o formato especificado. O método SetCurrentMediaType não altera a lista de tipos preferenciais.
O código a seguir mostra como obter o manipulador de tipo de mídia, enumerar os tipos de mídia preferenciais e definir o tipo de mídia. Este exemplo pressupõe que o aplicativo tenha algum algoritmo, não mostrado aqui, para selecionar o tipo de mídia. As especificidades dependerão muito do aplicativo.
HRESULT hr = S_OK;
DWORD cTypes = 0;
BOOL bTypeOK = FALSE;
IMFMediaTypeHandler *pHandler = NULL;
IMFMediaType *pMediaType = NULL;
hr = pStreamDesc->GetMediaTypeHandler(&pHandler);
if (SUCCEEDED(hr))
{
hr = pHandler->GetMediaTypeCount(&cTypes);
}
if (SUCCEEDED(hr))
{
for (DWORD iType = 0; iType < cTypes; iType++)
{
hr = pHandler->GetMediaTypeByIndex(iType, &pMediaType);
if (FAILED(hr))
{
break;
}
/* Examine the media type. (Not shown.) */
/* If this media type is acceptable, set the media type. */
if (bTypeOK)
{
hr = pHandler->SetCurrentMediaType(pMediaType);
break;
}
SAFE_RELEASE(pMediaType);
}
}
SAFE_RELEASE(pMediaType);
SAFE_RELEASE(pHandler);
Tópicos relacionados