Compartir a través de


Estados de filtro

[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEnginey captura de audio y 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 captura de audio y vídeo 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.

Los filtros tienen tres estados posibles: detenidos, en pausa y en ejecución. El propósito del estado en pausa es indicar los datos del grafo, de modo que un comando de ejecución responda inmediatamente. El Administrador de gráficos de filtros controla todas las transiciones de estado. Cuando una aplicación llama a IMediaControl::Run, IMediaControl::P auseo IMediaControl::Stop, el Administrador de gráficos de filtros llama al método IMediaFilter correspondiente en todos los filtros. Las transiciones entre detenidas y en ejecución siempre pasan por el estado en pausa, por lo que si la aplicación llama a Ejecutar en un gráfico detenido, el Administrador de gráficos de filtros pausa el gráfico antes de ejecutarlo.

Para la mayoría de los filtros, los estados en ejecución y en pausa son idénticos. Tenga en cuenta el siguiente gráfico de filtros:

Representador de > transformación de > de origen

Supongamos por ahora que el filtro de origen no es un origen de captura activa. Cuando el filtro de origen se pausa, crea un subproceso que genera nuevos datos y lo escribe en muestras multimedia lo antes posible. El subproceso "inserta" los ejemplos de bajada llamando a IMemInputPin::Receive en el pin de entrada del filtro de transformación. El filtro de transformación recibe los ejemplos en el subproceso del filtro de origen. Puede usar un subproceso de trabajo para entregar los ejemplos al representador, pero normalmente los entrega en el mismo subproceso. Mientras el representador está en pausa, espera a recibir un ejemplo. Después de recibir uno, bloquea y mantiene esa muestra indefinidamente. Si es un representador de vídeo, muestra el ejemplo como una imagen de póster y vuelve a dibujar la imagen según sea necesario.

En este punto, la secuencia está totalmente preparada para su representación. Si el gráfico permanece en pausa, las muestras se "acumularán" en el gráfico detrás del primer ejemplo, hasta que cada filtro se bloquee en Recibir o IMemAllocator::GetBuffer. Sin embargo, no se pierden datos. Una vez desbloqueado el subproceso de origen, simplemente se reanuda desde el punto donde se bloqueó.

El filtro de origen y el filtro de transformación omiten la transición de pausa a en ejecución; simplemente continúan procesando los datos lo más rápido posible. Pero cuando se ejecuta el representador, comienza a representar ejemplos. En primer lugar, representa el ejemplo que tenía mientras estaba en pausa. A continuación, cada vez que recibe un nuevo ejemplo, calcula el tiempo de presentación del ejemplo. (Para obtener más información, consulte hora y relojes en DirectShow). El representador contiene cada ejemplo hasta el momento de la presentación, en cuyo punto representa el ejemplo. Mientras espera el tiempo de presentación, se bloquea en el método Receive o recibe nuevos ejemplos en un subproceso de trabajo con una cola. Los filtros ascendentes del representador no están implicados en la programación.

Los orígenes dinámicos, como los dispositivos de captura, son una excepción a esta arquitectura general. Con un origen en directo, no es adecuado indicar los datos de antemano. La aplicación puede pausar el gráfico y esperar mucho tiempo antes de ejecutarlo. El gráfico no debe representar ejemplos "obsoletos". Por lo tanto, un origen activo no genera muestras mientras se pausa, solo mientras se ejecuta. Para indicar este hecho al Administrador de gráficos de filtros, el método IMediaFilter::GetState devuelve VFW_S_CANT_CUE. Este código de retorno indica que el filtro ha cambiado al estado en pausa, aunque el representador no haya recibido ningún dato.

Cuando se detiene un filtro, rechaza más muestras que se le entregan. Los filtros de origen apagan sus subprocesos de streaming y otros filtros apagan los subprocesos de trabajo que pueden haber creado. Los anclajes descommiten sus asignadores.

Transiciones de estado

El Administrador de gráficos de filtros lleva a cabo todas las transiciones de estado en orden ascendente, empezando por el representador y trabajando hacia atrás hasta el filtro de origen. Este orden es necesario para evitar que se quiten las muestras y para evitar que el grafo se interbloquee. Las transiciones de estado más cruciales están entre pausadas y detenidas:

  • Detenido en pausa: a medida que cada filtro se pausa, está listo para recibir muestras del siguiente filtro. El filtro de origen es el último en pausar. Crea el subproceso de streaming y comienza a entregar ejemplos. Dado que todos los filtros de bajada están en pausa, ningún filtro rechaza ninguna muestra. El Administrador de gráficos de filtros no completa la transición hasta que cada representador del grafo haya recibido un ejemplo (con la excepción de los orígenes activos, como se ha descrito anteriormente).
  • Pausada para detener: cuando un filtro se detiene, libera los ejemplos que contiene, lo que desbloquea los filtros ascendentes que esperan en GetBuffer. Si el filtro está esperando un recurso dentro del método Receive, deja de esperar y vuelve de Receive, que desbloquea el filtro de llamada. Por lo tanto, cuando el Administrador de gráficos de filtros detiene el siguiente filtro ascendente, ese filtro no está bloqueado en GetBuffer o Receivey puede responder al comando stop. El filtro ascendente puede entregar algunos ejemplos adicionales antes de obtener el comando stop, pero el filtro de bajada simplemente los rechaza, porque ya se detuvo.

Flujo de datos en el De gráfico de filtros