Controllo di un grafico di acquisizione
[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEnginee Acquisizione audio/video in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente di usare un nuovo codice MediaPlayer, IMFMediaEngine e Acquisizione audio/video in Media Foundation anziché 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 acquisirlo. È 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 di categoria pin. Il secondo parametro offre il tipo di media. 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 tramite 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 di evento. Pertanto, lParam2 nell'evento start è uguale a wStartCookiee lParam2 nell'evento di arresto è uguale a wStopCookie. Il codice seguente illustra come ottenere questi eventi:
while (hr = pEvent->GetEvent(&evCode, ¶m1, ¶m2, 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 gli orari di avvio e arresto.
Valore | Inizio | Fermarsi |
---|---|---|
MAXLONGLONG | Non avviare mai questo streaming. | Non fermarti finché il grafico non si ferma. |
NULL | Iniziare 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, questo creerà un gap nei timestamp. Durante la riproduzione, il video sembrerà bloccarsi durante l'intervallo (a seconda del formato del file).
Controllare il flusso di anteprima
Per controllare il pin di anteprima, chiamare ControlStream ma impostare il primo parametro su PIN_CATEGORY_PREVIEW. Questo 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 hanno 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 delle porte video, tuttavia, il metodo avrà esito negativo. In tal caso, un altro approccio consiste nel nascondere la finestra video. Effettuare una query sul grafico per IVideoWindowe usare il metodo IVideoWindow::put_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::put_AutoShow con il valore OAFALSE prima di eseguire il grafo, il filtro Video Renderer 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 recapitare 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 parallelo. In caso contrario, il filtro mux potrebbe bloccarsi in attesa di un flusso, mentre tenta di intervallare 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 utilizza l'interfaccia IAMStreamControl, che è esposta sui pin del filtro di cattura, sul filtro Smart Tee (se presente) ed eventualmente sul filtro mux. È possibile usare direttamente questa interfaccia, invece di chiamare ControlStream, anche se non vi è alcun vantaggio specifico per farlo.
Argomenti correlati