Información general sobre Data Flow en DirectShow

[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.

En esta sección se proporciona información general sobre cómo funciona el flujo de datos en DirectShow. Los detalles se pueden encontrar en otras secciones de la documentación.

Los datos se mantienen en búferes, que son simplemente matrices de bytes. Cada búfer se ajusta mediante un objeto COM denominado ejemplo multimedia, que implementa la interfaz IMediaSample . Los ejemplos se crean mediante otro tipo de objeto, denominado asignador, que implementa la interfaz IMemAllocator . Se asigna un asignador para cada conexión de patillas, aunque dos o más conexiones de patillas podrían compartir el mismo asignador. En la imagen siguiente se muestra este proceso.

búferes, ejemplos y asignadores

Cada asignador crea un grupo de ejemplos multimedia y asigna los búferes para cada ejemplo. Cada vez que un filtro necesita rellenar un búfer con datos, solicita un ejemplo del asignador mediante una llamada a IMemAllocator::GetBuffer. Si el asignador tiene muestras que no están actualmente en uso por otro filtro, el método GetBuffer devuelve inmediatamente con un puntero al ejemplo. Si todos los ejemplos del asignador están en uso, el método se bloquea hasta que un ejemplo esté disponible. Cuando el método devuelve un ejemplo, el filtro coloca los datos en el búfer, establece las marcas adecuadas en la muestra (normalmente, incluida una marca de tiempo) y entrega la muestra de bajada.

Cuando un filtro de representador recibe un ejemplo, comprueba la marca de tiempo y se mantiene en la muestra hasta que el reloj de referencia del gráfico de filtro indica que se deben representar los datos. Después de que el filtro represente los datos, libera el ejemplo. El ejemplo no vuelve al grupo de muestras del asignador hasta que el recuento de referencias del ejemplo es cero, lo que significa que cada filtro ha liberado la muestra. En la imagen siguiente se muestra este proceso.

descodificador esperando un ejemplo de medio gratuito

El filtro ascendente podría ejecutarse delante del representador, es decir, podría rellenar los búferes más rápido que el representador los consume. Incluso así, los ejemplos no se representan al principio, ya que el representador contiene cada uno hasta su tiempo de presentación. Además, el filtro ascendente no sobrescribirá los búferes accidentalmente, ya que GetSample solo devuelve muestras que no están en uso. La cantidad por la que se puede ejecutar el filtro ascendente viene determinada por el número de muestras del grupo del asignador.

En el diagrama anterior solo se muestra un asignador, pero normalmente hay varios asignadores por secuencia. Por lo tanto, cuando el representador libera un ejemplo, puede tener un efecto en cascada. En el diagrama siguiente se muestra una situación en la que un descodificador contiene un fotograma de vídeo comprimido mientras espera a que el representador libere un ejemplo. Un filtro del analizador también está esperando a que el descodificador libere un ejemplo.

dos filtros en espera de ejemplos

Cuando el representador libera su ejemplo, la llamada pendiente del descodificador a GetBuffer devuelve. Después, el descodificador puede descodificar el fotograma de vídeo comprimido y liberar la muestra que estaba manteniendo, lo que desbloquea la llamada a GetBuffer pendiente del analizador.

Data Flow en el gráfico de filtros