Creación del grafo de recompresión
[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.
Un gráfico de filtros típico para la recompresión de archivos AVI tiene el siguiente aspecto:
El filtro divisor AVI extrae datos del filtro de origen de archivos (Async) y lo analiza en secuencias de vídeo y audio. El descomprimor de vídeo descodifica el vídeo comprimido, donde se vuelve a comprimir por el compresor de vídeo. La elección de descompresores depende del archivo de origen; Se controlará automáticamente mediante Intelligent Connect. La aplicación debe elegir el compresor, normalmente presentando una lista al usuario. (Consulte Elección de un filtro de compresión).
A continuación, el vídeo comprimido va al filtro mux avi. La secuencia de audio de este ejemplo no está comprimida, por lo que pasa directamente del divisor AVI a la mux avi. Avi Mux interpone las dos secuencias y el filtro de escritura de archivos escribe la salida en el disco. Tenga en cuenta que se requiere la mux avi incluso si el archivo original no tiene una secuencia de audio.
La manera más fácil de crear este grafo de filtro es usar capture Graph Builder, que es un componente directShow para compilar gráficos de captura y otros gráficos de filtros personalizados.
Para empezar, llame a CoCreateInstance para crear el Generador de grafos de captura:
ICaptureGraphBuilder2 *pBuild = NULL;
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,
NULL, CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2, (void **)&pBuild);
A continuación, use capture Graph Builder para compilar el grafo de filtro:
- Compile la sección de representación del grafo, que incluye el filtro Mux avi y file Writer.
- Agregue el filtro de origen y el filtro de compresión al gráfico.
- Conecte el filtro de origen al filtro MUX. El generador de gráficos de captura inserta los filtros divisores y descodificadores necesarios para analizar el archivo de origen. También puede enrutar las secuencias de vídeo y audio a través de filtros de compresión.
En las secciones siguientes se explica cada uno de estos pasos.
Compilación de la sección de representación
Para compilar la sección de representación del gráfico, llame al método ICaptureGraphBuilder2::SetOutputFileName . Este método toma parámetros de entrada que especifican el subtipo multimedia para la salida y el nombre del archivo de salida. Devuelve punteros al filtro MUX y al escritor de archivos. El filtro MUX es necesario para la siguiente fase de creación de grafos. El puntero al sistema de escritura de archivos no es necesario para este ejemplo, de modo que el parámetro pueda ser NULL:
IBaseFilter *pMux = NULL;
hr = pBuild->SetOutputFileName(
&MEDIASUBTYPE_Avi, // File type.
wszOutputFile, // File name, as a wide-character string.
&pMux, // Receives a pointer to the multiplexer.
NULL); // Receives a pointer to the file writer.
Cuando el método vuelva, el filtro MUX tiene un recuento de referencias pendiente, por lo que asegúrese de liberar el puntero más adelante.
En el diagrama siguiente se muestra el gráfico de filtros en este momento.
El filtro MUX expone dos interfaces para controlar el formato AVI:
- Interfaz IConfigInterleaving: establece el modo de intercalación.
- IConfigAviMux Interface: establece la secuencia maestra y el índice de compatibilidad de AVI.
Agregar los filtros de origen y compresión
El siguiente paso consiste en agregar los filtros de compresión y origen al gráfico de filtros. Capture Graph Builder crea automáticamente una instancia del Administrador de gráficos de filtros cuando se llama a SetOutputFileName. Obtenga un puntero a él llamando al método ICaptureGraphBuilder2::GetFiltergraph :
IGraphBuilder *pGraph = NULL;
hr = pBuild->GetFiltergraph(&pGraph);
Ahora llame al método IGraphBuilder::AddSourceFilter para agregar el filtro de origen de archivo asincrónico y el método IFilterGraph::AddFilter para agregar el compresor de vídeo:
IBaseFilter *pSrc = NULL;
hr = pGraph->AddSourceFilter(wszInputFile, L"Source Filter", &pSrc);
hr = pGraph->AddFilter(pVComp, L"Compressor");
En este momento, el filtro de origen y el filtro de compresión no están conectados a nada más en el gráfico, como se muestra en la ilustración siguiente:
Conexión del origen a la mux
El último paso es conectar el filtro de origen al filtro Mux avi, a través del compresor de vídeo. Use el método ICaptureGraphBuilder2::RenderStream , que conecta un pin de salida en el filtro de origen a un filtro receptor especificado, opcionalmente a través de un filtro de compresión.
Los dos primeros parámetros especifican cuáles de las patillas del filtro de origen se van a conectar mediante la designación de una categoría de patillas y un tipo de medio. El filtro de origen de archivo asincrónico tiene solo un pin de salida, por lo que estos parámetros deben ser NULL. Los tres parámetros siguientes especifican el filtro de origen, el filtro de compresión (si existe) y el filtro Mux.
En el ejemplo de código siguiente se representa la secuencia de vídeo a través del compresor de vídeo:
hr = pBuild->RenderStream(
NULL, // Output pin category
NULL, // Media type
pSrc, // Source filter
pVComp, // Compression filter
pMux); // Sink filter (the AVI Mux)
En el diagrama siguiente se muestra el gráfico de filtros hasta ahora.
Suponiendo que el archivo de origen tiene una secuencia de audio, el filtro divisor AVI ha creado un pin de salida para el audio. Para conectar este pin, vuelva a llamar a RenderStream:
hr = pBuild->RenderStream(NULL, NULL, pSrc, NULL, pMux);
Aquí no se especifica ningún filtro de compresión. El pin de salida del filtro de origen ya está conectado, por lo que el método RenderStream busca un pin de salida no conectado en el filtro divisor. Encuentra el pin de audio y lo conecta directamente al filtro MUX. Si el archivo de origen no tiene una secuencia de audio, se producirá un error en la segunda llamada a RenderStream. Este es el comportamiento esperado. El gráfico se completa después de la primera llamada a RenderStream, por lo que el error en la segunda llamada es inofensivo.
En este ejemplo, el orden de las dos llamadas renderStream es importante. Dado que la segunda llamada no especifica un compresor, conectará cualquier pin no conectado desde el divisor AVI. Si realiza esta llamada antes de la otra, puede conectar la secuencia de vídeo a avi Mux, sin el compresor de vídeo. Por lo tanto, primero debe producirse la llamada más específica (con el filtro de compresión).
En la explicación anterior se ha asumido que el archivo de origen es un archivo AVI. Sin embargo, esta técnica también funciona con otros tipos de archivo, como archivos MPEG. El gráfico de filtros resultante será algo diferente.
Temas relacionados