Descritores de Apresentação
Um de apresentação é um conjunto de fluxos de mídia relacionados que compartilham um tempo de apresentação comum. 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 . Estes descrevem os fluxos na apresentação. Os fluxos podem ser selecionados ou desmarcados. Apenas 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 fontes de mídia
Cada fonte de mídia fornece um descritor de apresentação que descreve a configuração padrão para a fonte. 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 IMFPresentationDescriptor ponteiro.
Você pode modificar o descritor de apresentação da fonte 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 fonte.
Para obter o número de fluxos, ligue IMFPresentationDescriptor::GetStreamDescriptorCount. Para obter o descritor de fluxo para um fluxo, chame IMFPresentationDescriptor::GetStreamDescriptorByIndex e passe o índice do fluxo. Os fluxos são indexados a partir do zero. O GetStreamDescriptorByIndex método retorna um ponteiro IMFStreamDescriptor. Ele também retorna um sinalizador booleano indicando se o fluxo está selecionado. Se o fluxo for selecionado, a fonte de mídia produzirá dados para esse fluxo. Caso contrário, a fonte não produz dados para esse fluxo. Para selecionar um fluxo, chame IMFPresentationDescriptor::SelectStream com o índice do fluxo. Para cancelar a seleção de 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 para 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 IMFMediaTypeHandler ponteiro.
Se você quiser simplesmente saber que tipo de dados estão no fluxo, como áudio ou vídeo, ligue 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 de tipo principal pode ser a única informação de formato necessária.
Se seu aplicativo precisar de informações mais detalhadas sobre o formato atual, ligue IMFMediaTypeHandler::GetCurrentMediaType. Esse método retorna um ponteiro para o IMFMediaType interface do tipo de mídia. Use esta 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 suportados para o fluxo. Para obter o tamanho da lista, ligue 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 amostragem mais altas são preferíveis a taxas de amostragem mais baixas. No entanto, não existe uma regra definitiva que regule a encomenda, pelo que deve tratá-la simplesmente como uma orientação.
A lista de tipos suportados pode não conter todos os tipos de mídia possíveis suportados pelo fluxo. Para testar se um determinado tipo de mídia é suportado, 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 SetCurrentMediaType método 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 da sua aplicação.
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