Selecionando um decodificador nos Serviços de Edição do DirectShow
[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]
[Não há suporte para essa API e pode ser alterada ou indisponível no futuro.]
Quando o DirectShow Editing Services (DES) renderiza um projeto de edição de vídeo, o Mecanismo de Renderização seleciona automaticamente os decodificadores necessários. Isso pode acontecer dentro do método IRenderEngine::ConnectFrontEnd ou dinamicamente durante a renderização.
Um usuário pode instalar vários decodificadores capazes de decodificar um arquivo específico. Quando vários decodificadores estão disponíveis, o DES usa o algoritmo Intelligent Connect para selecionar o decodificador.
Não há como o aplicativo especificar diretamente qual decodificador usar. No entanto, você pode escolher o decodificador indiretamente por meio da interface de retorno de chamada IAMGraphBuilderCallback . Ao implementar essa interface em seu aplicativo, você pode receber notificações durante o processo de criação de grafo e rejeitar determinados filtros do grafo.
Comece implementando uma classe que expõe a interface IAMGraphBuilderCallback :
class GraphBuilderCB : public IAMGraphBuilderCallback
{
public:
// Method declarations (not shown).
};
Em seguida, crie uma instância do Gerenciador de Grafo de Filtro e registre sua classe para receber notificações de retorno de chamada:
// Declare an instance of the callback object.
GraphBuilderCB GraphCB;
// Create the Filter Graph Manager.
CComPtr<IGraphBuilder> pGraph;
hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
if (FAILED(hr))
{
// Handle error (not shown).
}
// Register to receive the callbacks.
CComQIPtr<IObjectWithSite> pSite(pGraph);
if (pSite)
{
hr = pSite->SetSite((IUnknown*)&GraphCB);
}
Em seguida, crie o Mecanismo de Renderização e chame o método IRenderEngine::SetFilterGraph com um ponteiro para o Gerenciador de Gráficos de Filtro. Isso garante que o Mecanismo de Renderização não crie seu próprio Gerenciador de Grafo de Filtro, mas usa a instância que você configurou para retornos de chamada.
CComPtr<IRenderEngine> pRender;
hr = pRender.CoCreateInstance(CLSID_RenderEngine);
if (FAILED(hr))
{
// Handle error (not shown).
}
hr = pRender->SetFilterGraph(pGraph);
Quando o projeto é renderizado, o método IAMGraphBuilderCallback::SelectedFilter do aplicativo é chamado imediatamente antes que o Gerenciador de Grafo de Filtro crie um novo filtro. O método SelectedFilter recebe um ponteiro para uma interface IMoniker que representa um moniker para o filtro. Examine o moniker e, se você decidir rejeitar o filtro, retorne um código de falha do método SelectedFilter .
A parte difícil é identificar quais monikers representam decodificadores — e, em particular, quais monikers representam decodificadores que você deseja rejeitar. Uma solução é a seguinte:
Antes de renderizar o projeto, use o método IFilterMapper2::EnumMatchingFilters para criar uma lista de filtros registrados como aceitando o tipo de entrada desejado. Para tipos de compactação de áudio ou vídeo, essa lista deve ser mapeada para um conjunto de decodificadores.
O método EnumMatchingFilters retorna uma coleção de monikers. Para cada moniker na coleção, obtenha a propriedade DisplayName , conforme descrito em Usando o Mapeador de Filtro.
Armazene uma lista dos nomes de exibição, mas omita o nome de exibição que corresponde ao filtro que você deseja usar para decodificação. Os nomes de exibição para filtros de software têm o seguinte formato:
OLESTR("@device:sw:{CategoryGUID}\{FilterCLSID}");
onde
CategoryGUID
é o GUID da categoria de filtro e
FilterCLSID
é o CLSID do filtro. Para DMOs, o formato é o mesmo, mas é alterado
sw
paradmo
.A lista agora contém nomes de exibição para cada filtro que gera o tipo de mídia desejado, mas não é o filtro preferencial.
No método SelectedFilter, obtenha a propriedade DisplayName no moniker proposto e marcar-a na lista armazenada. Se o nome de exibição corresponder a uma entrada na lista, rejeite esse filtro. Caso contrário, aceite-o retornando S_OK.
Tópicos relacionados