Compartir a través de


Controlar un grafo de captura

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

La interfaz IMediaControl de Filter Graph Manager tiene métodos para ejecutar, detener y pausar todo el grafo. Sin embargo, si el gráfico de filtros tiene secuencias de captura y vista previa, es probable que quiera controlar las dos secuencias de forma independiente. Por ejemplo, es posible que quiera obtener una vista previa del vídeo sin capturarlo. Puede hacerlo a través del método ICaptureGraphBuilder2::ControlStream .

Nota:

Este método no funciona al capturar en un archivo de formato de sistemas avanzados (ASF).

 

Controlar el flujo de captura

El código siguiente establece la secuencia de captura de vídeo que se ejecutará durante cuatro segundos, empezando un segundo después de que se ejecute el grafo:

// Control the video capture stream. 
REFERENCE_TIME rtStart = 10000000, rtStop = 50000000;
const WORD wStartCookie = 1, wStopCookie = 2;  // Arbitrary values.
hr = pBuild->ControlStream(
    &PIN_CATEGORY_CAPTURE, // Pin category.
    &MEDIATYPE_Video,      // Media type.
    pCap,                 // Capture filter.
    &rtStart, &rtStop,     // Start and stop times.
    wStartCookie, wStopCookie  // Values for the start and stop events.
);
pControl->Run();

El primer parámetro especifica qué secuencia se va a controlar, como GUID de categoría de anclaje. El segundo parámetro proporciona el tipo de medio. El tercer parámetro es un puntero al filtro de captura. Para controlar todas las secuencias de captura del gráfico, establezca los parámetros segundo y tercero en NULL.

Los dos parámetros siguientes definen las horas en las que se iniciará y se detendrá la secuencia, en relación con la hora en que el grafo comienza a ejecutarse. Llame a IMediaControl::Run para ejecutar el grafo. Hasta que se ejecuta el grafo, el método ControlStream no tiene ningún efecto. Si el gráfico ya se está ejecutando, la configuración surte efecto inmediatamente.

Los dos últimos parámetros se usan para obtener notificaciones de eventos cuando se inicia y se detiene la secuencia. Para cada secuencia que controle mediante este método, el gráfico de filtros envía un par de eventos: EC_STREAM_CONTROL_STARTED cuando se inicia la secuencia y EC_STREAM_CONTROL_STOPPED cuando se detiene la secuencia. Los valores de wStartCookie y wStopCookie se usan como segundo parámetro de evento. Por lo tanto, lParam2 en el evento de inicio es igual a wStartCookie y lParam2 en el evento stop es igual a wStopCookie. En el código siguiente se muestra cómo obtener estos eventos:

while (hr = pEvent->GetEvent(&evCode, &param1, &param2, 0), SUCCEEDED(hr))
{
    switch (evCode)
    {
    case EC_STREAM_CONTROL_STARTED: 
    // param2 == wStartCookie
    break;

    case EC_STREAM_CONTROL_STOPPED: 
    // param2 == wStopCookie
    break;
    
    } 
    pEvent->FreeEventParams(evCode, param1, param2);
}

El método ControlStream define algunos valores especiales para las horas de inicio y detención.

Valor Inicio Stop
MAXLONGLONG Nunca inicie esta secuencia. No detenga hasta que se detenga el gráfico.
NULL Se inicia inmediatamente cuando se ejecuta el grafo. Deténgase inmediatamente.

 

Por ejemplo, el código siguiente detiene la secuencia de captura inmediatamente:

pBuild->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap,
    0, 0,     // Start and stop times.
    wStartCookie, wStopCookie); 

Aunque puede detener la secuencia de captura y reiniciarla más adelante, esto creará un intervalo en las marcas de tiempo. En la reproducción, el vídeo aparecerá detenido durante la brecha (según el formato de archivo).

Control de la secuencia de vista previa

Para controlar el pin de vista previa, llame a ControlStream , pero establezca el primer parámetro en PIN_CATEGORY_PREVIEW. Esto funciona igual que para PIN_CATEGORY_CAPTURE, salvo que no se pueden usar tiempos de referencia para especificar el inicio y la detención, ya que los fotogramas de vista previa no tienen marcas de tiempo. Por lo tanto, debe usar NULL o MAXLONGLONG. Use NULL para iniciar la secuencia de vista previa:

pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
    NULL,    // Start now.
    0,       // (Don't care.)
    wStartCookie, wStopCookie); 

Use MAXLONGLONG para detener la secuencia de vista previa:

pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
    0,               // (Don't care.)
    MAXLONGLONG,     // Stop now.
    wStartCookie, wStopCookie); 

No importa si la secuencia de vista previa procede de un pin de vista previa en el filtro de captura o del filtro Smart Tee. El método ControlStream funciona de cualquier manera.

Sin embargo, en el caso de las patillas de puerto de vídeo, se producirá un error en el método . En ese caso, otro enfoque es ocultar la ventana de vídeo. Consulte el gráfico de IVideoWindow y use el método IVideoWindow::p ut_Visible para mostrar u ocultar la ventana.

// Hide the video window.
IVideoWindow *pVidWin = 0;
hr = pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVidWin);
if (SUCCEEDED(hr))
{
    pVidWin->put_Visible(OAFALSE);
    pVidWin->Release();
}

Además, si llama a IVideoWindow::p ut_AutoShow con el valor OAFALSE antes de ejecutar el gráfico, el filtro Video Renderer oculta la ventana hasta que especifique lo contrario. De forma predeterminada, Video Renderer muestra la ventana al ejecutar el gráfico.

Comentarios sobre el control de flujo

El comportamiento predeterminado de un pin es entregar muestras cuando se ejecuta el grafo. Por ejemplo, supongamos que llama a ControlStream con PIN_CATEGORY_CAPTURE pero no con PIN_CATEGORY_PREVIEW. Al ejecutar el grafo, la secuencia de vista previa se ejecutará inmediatamente, mientras que la secuencia de captura se ejecutará en cualquier momento especificado en ControlStream.

Si va a capturar más de una secuencia y enviarlos a un filtro mux (por ejemplo, si está capturando audio y vídeo en un archivo AVI), debe controlar ambas secuencias en conjunto. De lo contrario, el filtro mux podría bloquear la espera de una secuencia, ya que intenta intercalar las dos secuencias. Establezca las mismas horas de inicio y detención en todas las secuencias de captura antes de ejecutar el grafo:

pBuild->ControlStream(&PIN_CATEGORY_CAPTURE, 
    
NULL, NULL,       // All capture streams.
    &rtStart, rtStop, 
    wStartCookie, wStopCookie); 

Internamente, el método ControlStream usa la interfaz IAMStreamControl , que se expone en las patillas del filtro de captura, el filtro Smart Tee (si está presente) y posiblemente el filtro mux. Puede usar esta interfaz directamente, en lugar de llamar a ControlStream, aunque no hay ninguna ventaja particular para hacerlo.

Captura de vídeo