Condividi tramite


Acquisizione di video in un file AVI

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

La figura seguente mostra il grafico più semplice possibile per l'acquisizione di video in un file AVI.

grafico di acquisizione video avi

Il filtro AVI Mux accetta il flusso video dal pin di acquisizione e lo inserisce in un flusso AVI. Un flusso audio può anche essere connesso al filtro AVI Mux, nel qual caso il mux interlerebbe i due flussi. Il filtro Writer file scrive il flusso AVI su disco.

Per compilare il grafico, iniziare chiamando il metodo ICaptureGraphBuilder2::SetOutputFileName , come indicato di seguito:

IBaseFilter *pMux;
hr = pBuild->SetOutputFileName(
    &MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
    L"C:\\Example.avi", // File name.
    &pMux,              // Receives a pointer to the mux.
    NULL);              // (Optional) Receives a pointer to the file sink.

Il primo parametro specifica il tipo di file , in questo caso AVI. Il secondo parametro fornisce il nome del file. Per AVI, il metodo SetOutputFileName crea il filtro AVI Mux e il filtro Writer file e li aggiunge al grafico. Imposta anche il nome del file nel filtro Writer file chiamando il metodo IFileSinkFilter::SetFileName e connette i due filtri. Il metodo restituisce un puntatore al mux AVI nel terzo parametro. Facoltativamente, restituisce un puntatore all'interfaccia IFileSinkFilter nel quarto parametro. Se non è necessaria questa interfaccia, è possibile impostare questo parametro su NULL, come illustrato nell'esempio precedente.

Chiamare quindi il metodo ICaptureGraphBuilder2::RenderStream per connettere il filtro di acquisizione a AVI Mux, come indicato di seguito:

hr = pBuild->RenderStream(
    &PIN_CATEGORY_CAPTURE, // Pin category.
    &MEDIATYPE_Video,      // Media type.
    pCap,                  // Capture filter.
    NULL,                  // Intermediate filter (optional).
    pMux);                 // Mux or file sink filter.

// Release the mux filter.
pMux->Release();

Il primo parametro fornisce la categoria di pin, che è PIN_CATEGORY_CAPTURE per l'acquisizione. Il secondo parametro fornisce il tipo di supporto. Il terzo parametro è un puntatore all'interfaccia IBaseFilter del filtro di acquisizione. Il quarto parametro è facoltativo; consente di instradare il flusso video attraverso un filtro intermedio, ad esempio un codificatore, prima di passarlo al filtro mux. In caso contrario, impostare questo parametro su NULL, come illustrato nell'esempio precedente. Il quinto parametro è il puntatore al filtro mux. Questo puntatore viene ottenuto chiamando il metodo SetOutputFileName.

Per acquisire audio, chiamare RenderStream con il tipo di supporto MEDIATYPE_Audio. Se si acquisiscono audio e video da due dispositivi separati, è consigliabile creare il flusso audio del flusso master. Ciò consente di evitare la deriva tra i due flussi, perché il filtro AVI Mux regola la frequenza di riproduzione nel flusso video in modo che corrisponda al flusso audio. Per impostare il flusso master, chiamare il metodo IConfigAviMux::SetMasterStream nel filtro AVI Mux:

IConfigAviMux *pConfigMux = NULL;
hr = pMux->QueryInterface(IID_IConfigAviMux, (void**)&pConfigMux);
if (SUCCEEDED(hr))
{
    pConfigMux->SetMasterStream(1);
    pConfigMux->Release();
}

Il parametro setMasterStream è il numero di flusso, determinato dall'ordine in cui si chiama RenderStream. Ad esempio, se si chiama RenderStream prima per il video e quindi per l'audio, il video è stream 0 e l'audio è stream 1.

È anche possibile impostare il modo in cui il filtro AVI Mux interlaccia i flussi audio e video chiamando il metodo IConfigInterleaving::p ut_Mode .

IConfigInterleaving *pInterleave = NULL;
hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave);
if (SUCCEEDED(hr))
{
    pInterleave->put_Mode(INTERLEAVE_CAPTURE);
    pInterleave->Release();
}

Con il flag INTERLEAVE_CAPTURE, AVI Mux esegue l'interleaving a una frequenza adatta per l'acquisizione di video. È anche possibile usare INTERLEAVE_NONE, ovvero nessuna interleaving: avi Mux scriverà semplicemente i dati nell'ordine in cui arriva. Il flag INTERLEAVE_FULL indica che il mux AVI esegue l'interleaving completo; tuttavia, questa modalità è meno adatta per l'acquisizione di video perché richiede il più sovraccarico.

Codifica del flusso video

È possibile codificare il flusso video inserendo un filtro codificatore tra il filtro di acquisizione e il filtro AVI Mux. Usare l'enumeratore dispositivo di sistema o il filtro mapper per selezionare un filtro del codificatore. Per altre informazioni, vedere Enumerazione di dispositivi e filtri.

Specificare il filtro del codificatore come quarto parametro per RenderStream, illustrato in grassetto nell'esempio seguente:

IBaseFilter *pEncoder;
/* Create the encoder filter (not shown). */
// Add it to the filter graph.
pGraph->AddFilter(pEncoder, L"Encoder");

/* Call SetOutputFileName as shown previously. */

// Render the stream.
hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, 
    pCap, 
pEncoder, pMux);
pEncoder->Release();

Il filtro del codificatore può supportare IAMVideoCompression o altre interfacce per impostare i parametri di codifica. Per un elenco delle interfacce possibili, vedere Codifica file e interfacce di decodifica.

Acquisizione di video in un file