Compartir a través de


Seleccionar un descodificador en DirectShow Editing Services

[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.

[Esta API no se admite y puede modificarse o no estar disponible en el futuro].

Cuando DirectShow Editing Services (DES) representa un proyecto de edición de vídeo, el motor de representación selecciona automáticamente los descodificadores necesarios. Esto puede ocurrir dentro del método IRenderEngine::ConnectFrontEnd , o bien dinámicamente durante la representación.

Un usuario puede instalar varios descodificadores que puedan descodificar un archivo determinado. Cuando hay varios descodificadores disponibles, DES usa el algoritmo Intelligent Connect para seleccionar el descodificador.

No hay forma de que la aplicación especifique directamente qué descodificador se va a usar. Sin embargo, puede elegir el descodificador indirectamente a través de la interfaz de devolución de llamada IAMGraphBuilderCallback . Al implementar esta interfaz en la aplicación, puede recibir notificaciones durante el proceso de creación de grafos y rechazar determinados filtros del gráfico.

Empiece por implementar una clase que exponga la interfaz IAMGraphBuilderCallback :

class GraphBuilderCB : public IAMGraphBuilderCallback
{
public:
     // Method declarations (not shown).
};

A continuación, cree una instancia de Filter Graph Manager y registre la clase para recibir notificaciones de devolución de llamada:

// 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);
}

A continuación, cree el motor de representación y llame al método IRenderEngine::SetFilterGraph con un puntero al Administrador de gráficos de filtros. Esto garantiza que el motor de representación no cree su propio Administrador de gráficos de filtros, sino que usa la instancia que ha configurado para las devoluciones de llamada.

CComPtr<IRenderEngine> pRender;
hr = pRender.CoCreateInstance(CLSID_RenderEngine);
if (FAILED(hr))
{
    // Handle error (not shown).
}

hr = pRender->SetFilterGraph(pGraph);

Cuando se representa el proyecto, se llama al método IAMGraphBuilderCallback::SelectedFilter de la aplicación inmediatamente antes de que filter Graph Manager cree un nuevo filtro. El método SelectedFilter recibe un puntero a una interfaz IMoniker que representa un moniker para el filtro. Examine el moniker y, si decide rechazar el filtro, devuelva un código de error del método SelectedFilter .

La parte difícil es identificar qué monikers representan descodificadores, y en particular, qué monikers representan descodificadores que desea rechazar. Una solución es la siguiente:

  • Antes de representar el proyecto, use el método IFilterMapper2::EnumMatchingFilters para crear una lista de filtros registrados como aceptación del tipo de entrada deseado. Para los tipos de compresión de audio o vídeo, esta lista debe asignarse a un conjunto de descodificadores.

  • El método EnumMatchingFilters devuelve una colección de monikers. Para cada moniker de la colección, obtenga la propiedad DisplayName , como se describe en Uso del asignador de filtros.

  • Almacene una lista de los nombres para mostrar, pero omita el nombre para mostrar que coincida con el filtro que desea usar para descodificar. Los nombres para mostrar de los filtros de software tienen el siguiente formato:

    OLESTR("@device:sw:{CategoryGUID}\{FilterCLSID}");
    

    where

    CategoryGUID
    

    es el GUID de la categoría de filtro y

    FilterCLSID
    

    es el CLSID del filtro. En el caso de las DMV, el formato es el mismo, pero cambia sw a dmo.

    La lista ahora contiene nombres para mostrar para cada filtro que genera el tipo de medio deseado, pero no es el filtro preferido.

  • En el método SelectedFilter , obtenga la propiedad DisplayName en el moniker propuesto y compruébalo en la lista almacenada. Si el nombre para mostrar coincide con una entrada de la lista, rechace ese filtro. De lo contrario, para aceptarlo, devuelva S_OK.

Representación de un proyecto