Controllo di un grafico di acquisizione

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation invece di DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

L'interfaccia IMediaControl di Filter Graph Manager include metodi per l'esecuzione, l'arresto e la sospensione dell'intero grafico. Se il grafico dei filtri include flussi di acquisizione e anteprima, tuttavia, è probabile che si voglia controllare i due flussi in modo indipendente. Ad esempio, è possibile visualizzare in anteprima il video senza catturarlo. È possibile eseguire questa operazione tramite il metodo ICaptureGraphBuilder2::ControlStream .

Nota

Questo metodo non funziona durante l'acquisizione in un file ASF (Advanced Systems Format).

 

Controllo del flusso di acquisizione

Il codice seguente imposta l'esecuzione del flusso di acquisizione video per quattro secondi, a partire da un secondo dopo l'esecuzione del grafico:

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

Il primo parametro specifica il flusso da controllare, come GUID della categoria di pin. Il secondo parametro fornisce il tipo di supporto. Il terzo parametro è un puntatore al filtro di acquisizione. Per controllare tutti i flussi di acquisizione nel grafico, impostare il secondo e il terzo parametro su NULL.

I due parametri successivi definiscono gli orari in cui il flusso verrà avviato e arrestato, in relazione all'ora in cui il grafico inizia l'esecuzione. Chiamare IMediaControl::Run per eseguire il grafico. Finché non si esegue il grafico, il metodo ControlStream non ha alcun effetto. Se il grafico è già in esecuzione, le impostazioni diventano effettive immediatamente.

Gli ultimi due parametri vengono usati per ricevere notifiche degli eventi all'avvio e all'arresto del flusso. Per ogni flusso controllato usando questo metodo, il grafico del filtro invia una coppia di eventi: EC_STREAM_CONTROL_STARTED all'avvio del flusso e EC_STREAM_CONTROL_STOPPED quando il flusso si arresta. I valori di wStartCookie e wStopCookie vengono usati come secondo parametro dell'evento. Pertanto , lParam2 nell'evento start è uguale a wStartCookie e lParam2 nell'evento di arresto è uguale a wStopCookie. Il codice seguente illustra come ottenere questi eventi:

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

Il metodo ControlStream definisce alcuni valori speciali per l'ora di inizio e di arresto.

Valore Inizia Stop
MAXLONGLONG Non avviare mai questo flusso. Non arrestarsi fino all'arresto del grafico.
NULL Avvia immediatamente quando viene eseguito il grafico. Smettila immediatamente.

 

Ad esempio, il codice seguente arresta immediatamente il flusso di acquisizione:

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

Anche se è possibile arrestare il flusso di acquisizione e riavviarlo in un secondo momento, ciò creerà un divario nei timestamp. Durante la riproduzione, il video apparirà bloccato durante la distanza (a seconda del formato di file).

Controllo del flusso di anteprima

Per controllare il pin di anteprima, chiamare ControlStream , ma impostare il primo parametro su PIN_CATEGORY_PREVIEW. Questa operazione funziona esattamente come per PIN_CATEGORY_CAPTURE, ad eccezione del fatto che non è possibile usare i tempi di riferimento per specificare l'avvio e l'arresto, perché i fotogrammi di anteprima non dispongono di timestamp. Pertanto, è necessario utilizzare NULL o MAXLONGLONG. Usare NULL per avviare il flusso di anteprima:

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

Usare MAXLONGLONG per arrestare il flusso di anteprima:

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

Non importa se il flusso di anteprima proviene da un pin di anteprima nel filtro di acquisizione o dal filtro Smart Tee. Il metodo ControlStream funziona in entrambi i modi.

Per i pin della porta video, tuttavia, il metodo avrà esito negativo. In tal caso, un altro approccio consiste nel nascondere la finestra del video. Eseguire una query sul grafico per IVideoWindow e usare il metodo IVideoWindow::p ut_Visible per visualizzare o nascondere la finestra.

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

Inoltre, se si chiama IVideoWindow::p ut_AutoShow con il valore OAFALSE prima di eseguire il grafo, il filtro Del renderer video nasconde la finestra fino a quando non si specifica diversamente. Per impostazione predefinita, il Renderer video mostra la finestra quando si esegue il grafico.

Osservazioni sul controllo Di flusso

Il comportamento predefinito per un pin consiste nel fornire campioni quando viene eseguito il grafico. Si supponga, ad esempio, di chiamare ControlStream con PIN_CATEGORY_CAPTURE ma non con PIN_CATEGORY_PREVIEW. Quando si esegue il grafo, il flusso di anteprima verrà eseguito immediatamente, mentre il flusso di acquisizione verrà eseguito in qualsiasi momento specificato in ControlStream.

Se si acquisiscono più flussi e li si invia a un filtro mux, ad esempio se si acquisiscono audio e video in un file AVI, è necessario controllare entrambi i flussi in tandem. In caso contrario, il filtro mux potrebbe bloccare l'attesa di un flusso, perché tenta di interleavere i due flussi. Impostare gli stessi orari di avvio e arresto in tutti i flussi di acquisizione prima di eseguire il grafico:

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

Internamente, il metodo ControlStream usa l'interfaccia IAMStreamControl , esposta sui pin del filtro di acquisizione, il filtro Tee intelligente (se presente) ed eventualmente il filtro mux. È possibile usare direttamente questa interfaccia, anziché chiamare ControlStream, anche se non vi è alcun vantaggio particolare per farlo.

Acquisizione video