Creazione del grafico di ricompressione
[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, FMMediaEngine 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, FMMediaEngine e Audio/Video Capture 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.
Un grafico di filtro tipico per la ricompressione di file AVI è simile al seguente:
Il filtro splitter AVI esegue il pull dei dati dal filtro origine file (Async) e lo analizza in flussi video e audio. Il decompressore video decodifica il video compresso, dove viene ricompresso dal compressore video. La scelta di decompressori dipende dal file di origine; verrà gestito automaticamente da Intelligent Connect. L'applicazione deve scegliere il compressore, in genere presentando un elenco all'utente. Vedere Scelta di un filtro di compressione.
Il video compresso passa quindi al filtro Mux AVI. Il flusso audio in questo esempio non è compresso, quindi passa direttamente dall'AVI Splitter all'AVI Mux. Avi Mux interlea tra i due flussi e il filtro writer file scrive l'output su disco. Si noti che è necessario avi Mux anche se il file originale non ha un flusso audio.
Il modo più semplice per creare questo grafico di filtro consiste nell'usare Capture Graph Builder, che è un componente DirectShow per la creazione di grafici di acquisizione e altri grafici di filtro personalizzati.
Iniziare chiamando CoCreateInstance per creare Capture Graph Builder:
ICaptureGraphBuilder2 *pBuild = NULL;
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,
NULL, CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2, (void **)&pBuild);
Usare quindi Capture Graph Builder per compilare il grafico del filtro:
- Creare la sezione di rendering del grafico, che include il filtro AVI Mux e il writer di file.
- Aggiungere il filtro di origine e il filtro di compressione al grafico.
- Connettere il filtro di origine al filtro MUX. Il generatore di grafici di acquisizione inserisce qualsiasi filtro splitter e decodificatore necessario per analizzare il file di origine. Può anche instradare i flussi video e audio tramite filtri di compressione.
Le sezioni seguenti illustrano ognuno di questi passaggi.
Compilare la sezione Rendering
Per compilare la sezione di rendering del grafico, chiamare il metodo ICaptureGraphBuilder2::SetOutputFileName . Questo metodo accetta parametri di input che specificano il sottotipo multimediale per l'output e il nome del file di output. Restituisce puntatori al filtro MUX e al writer di file. Il filtro MUX è necessario per la fase successiva della compilazione del grafico. Il puntatore al writer di file non è necessario per questo esempio, in modo che il parametro possa essere NULL:
IBaseFilter *pMux = NULL;
hr = pBuild->SetOutputFileName(
&MEDIASUBTYPE_Avi, // File type.
wszOutputFile, // File name, as a wide-character string.
&pMux, // Receives a pointer to the multiplexer.
NULL); // Receives a pointer to the file writer.
Quando il metodo restituisce, il filtro MUX ha un numero di riferimenti in sospeso, quindi assicurarsi di rilasciare il puntatore in un secondo momento.
Il diagramma seguente mostra il grafico del filtro a questo punto.
Il filtro MUX espone due interfacce per controllare il formato AVI:
- Interfaccia IConfigInterleaving: imposta la modalità di interleaving.
- Interfaccia IConfigAviMux: imposta il flusso master e l'indice di compatibilità AVI.
Aggiungere i filtri di origine e compressione
Il passaggio successivo consiste nell'aggiungere i filtri di origine e compressione al grafico del filtro. Capture Graph Builder crea automaticamente un'istanza di Filter Graph Manager quando si chiama SetOutputFileName. Ottenere un puntatore a esso chiamando il metodo ICaptureGraphBuilder2::GetFiltergraph :
IGraphBuilder *pGraph = NULL;
hr = pBuild->GetFiltergraph(&pGraph);
Chiamare ora il metodo IGraphBuilder::AddSourceFilter per aggiungere il filtro Origine file asincrona e il metodo IFilterGraph::AddFilter per aggiungere il compressore video:
IBaseFilter *pSrc = NULL;
hr = pGraph->AddSourceFilter(wszInputFile, L"Source Filter", &pSrc);
hr = pGraph->AddFilter(pVComp, L"Compressor");
A questo punto, il filtro di origine e il filtro di compressione non sono connessi ad altri elementi nel grafico, come illustrato nella figura seguente:
Connettere l'origine al Mux
Il passaggio finale consiste nel connettere il filtro di origine al filtro AVI Mux tramite il compressore video. Usare il metodo ICaptureGraphBuilder2::RenderStream , che connette un pin di output al filtro di origine a un filtro sink specificato, facoltativamente tramite un filtro di compressione.
I primi due parametri specificano i pin del filtro di origine da connettere, progettando una categoria di pin e un tipo di supporto. Il filtro origine file asincrona ha un solo pin di output, quindi questi parametri devono essere NULL. I tre parametri successivi specificano il filtro di origine, il filtro di compressione (se presente) e il filtro Mux.
L'esempio di codice seguente esegue il rendering del flusso video tramite il compressore video:
hr = pBuild->RenderStream(
NULL, // Output pin category
NULL, // Media type
pSrc, // Source filter
pVComp, // Compression filter
pMux); // Sink filter (the AVI Mux)
Il diagramma seguente mostra il grafico del filtro finora.
Supponendo che il file di origine abbia un flusso audio, il filtro AVI Splitter ha creato un pin di output per l'audio. Per connettere questo pin, chiamare di nuovo RenderStream:
hr = pBuild->RenderStream(NULL, NULL, pSrc, NULL, pMux);
In questo caso non è specificato alcun filtro di compressione. Il pin di output del filtro di origine è già connesso, quindi il metodo RenderStream cerca un pin di output non connesso nel filtro splitter. Trova il pin audio e lo connette direttamente al filtro MUX. Se il file di origine non ha un flusso audio, la seconda chiamata a RenderStream avrà esito negativo. Si tratta di un comportamento previsto. Il grafico viene completato dopo la prima chiamata a RenderStream, quindi l'errore nella seconda chiamata è innocuo.
In questo esempio l'ordine delle due chiamate RenderStream è importante. Poiché la seconda chiamata non specifica un compressore, connetterà qualsiasi pin non connesso da AVI Splitter. Se si effettua questa chiamata prima dell'altra, potrebbe connettere il flusso video a AVI Mux, senza il compressore video. Pertanto, la chiamata più specifica (con il filtro di compressione) deve essere eseguita prima.
La discussione precedente presuppone che il file di origine sia un file AVI. Tuttavia, questa tecnica funziona anche con altri tipi di file, ad esempio file MPEG. Il grafico del filtro risultante sarà leggermente diverso.
Argomenti correlati