Aufzeichnen von Videos in einer AVI-Datei

Die folgende Abbildung zeigt das einfachste Diagramm zum Erfassen von Videos in einer AVI-Datei.

Avi Video Capture Graph

Der AVI Mux-Filter verwendet den Videodatenstrom vom Erfassungspin und verpackt ihn in einen AVI-Stream. Ein Audiostream kann auch mit dem AVI Mux-Filter verbunden werden. In diesem Fall würde der Mux die beiden Streams verschachteln. Der File Writer-Filter schreibt den AVI-Stream auf den Datenträger.

Um das Diagramm zu erstellen, rufen Sie zunächst wie folgt die ICaptureGraphBuilder2::SetOutputFileName-Methode auf:

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.

Der erste Parameter gibt den Dateityp an – in diesem Fall AVI. Der zweite Parameter gibt den Dateinamen an. Für AVI werden mit der SetOutputFileName-Methode der AVI Mux-Filter und der File Writer-Filter zusammengefügt und dem Diagramm hinzugefügt. Außerdem wird der Dateiname im File Writer-Filter festgelegt, indem die IFileSinkFilter::SetFileName-Methode aufgerufen wird, und die beiden Filter werden miteinander verbunden. Die -Methode gibt einen Zeiger auf den AVI Mux im dritten Parameter zurück. Optional wird ein Zeiger auf die IFileSinkFilter-Schnittstelle im vierten Parameter zurückgegeben. Wenn Sie diese Schnittstelle nicht benötigen, können Sie diesen Parameter auf NULL festlegen, wie im vorherigen Beispiel gezeigt.

Rufen Sie als Nächstes die ICaptureGraphBuilder2::RenderStream-Methode auf, um den Erfassungsfilter wie folgt mit dem AVI Mux zu verbinden:

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

Der erste Parameter gibt die Stecknadelkategorie an, d. h. PIN _ CATEGORY CAPTURE für die _ Erfassung. Der zweite Parameter gibt den Medientyp an. Der dritte Parameter ist ein Zeiger auf die IBaseFilter-Schnittstelle des Erfassungsfilters. Der vierte Parameter ist optional. Sie können den Videostream über einen Zwischenfilter wie einen Encoder weiterleiten, bevor Sie ihn an den Mux-Filter übergeben. Legen Sie andernfalls diesen Parameter auf NULL fest, wie im vorherigen Beispiel gezeigt. Der fünfte Parameter ist der Zeiger auf den mux-Filter. Dieser Zeiger wird durch Aufrufen der SetOutputFileName-Methode abgerufen.

Um Audio zu erfassen, rufen Sie RenderStream mit dem Medientyp MEDIATYPE _ Audio auf. Wenn Sie Audio- und Videodaten von zwei separaten Geräten erfassen, ist es eine gute Idee, den Audiostream zum Masterstream zu machen. Dies trägt dazu bei, Abweichungen zwischen den beiden Streams zu verhindern, da der AVI Mux-Filter die Wiedergaberate im Videostream an den Audiostream anpasst. Um den Masterstream festzulegen, rufen Sie die IConfigAviMux::SetMasterStream-Methode für den AVI Mux-Filter auf:

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

Der Parameter für SetMasterStream ist die Streamnummer, die durch die Reihenfolge bestimmt wird, in der Sie RenderStream aufrufen. Wenn Sie beispielsweise RenderStream zuerst für Video und dann für Audio aufrufen, ist das Video Stream 0 und das Audio ist Stream 1.

Sie können auch festlegen, wie der AVI Mux-Filter die Audio- und Videostreams interleaviert, indem Sie die IConfigInterleaving::p ut _ Mode-Methode aufrufen.

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

Mit dem INTERLEAVE _ CAPTURE-Flag führt der AVI Mux die Überlappung mit einer Rate durch, die für die Videoaufnahme geeignet ist. Sie können auch INTERLEAVE _ NONE verwenden, was bedeutet, dass keine Überlappung erfolgt. Der AVI Mux schreibt die Daten einfach in der Reihenfolge, in der sie eintreffen. Das INTERLEAVE _ FULL-Flag bedeutet, dass der AVI Mux vollständige Überlappungen durchführt. Dieser Modus ist jedoch weniger für die Videoaufnahme geeignet, da er den meisten Overheard erfordert.

Codieren des Videostreams

Sie können den Videostream codieren, indem Sie einen Encoderfilter zwischen dem Erfassungsfilter und dem AVI Mux-Filter einfügen. Verwenden Sie den Systemgeräte-Enumerator oder die Filterzuordnung, um einen Encoderfilter auszuwählen. (Weitere Informationen finden Sie unter Aufzählen von Geräten und Filtern.)

Geben Sie den Encoderfilter als vierten Parameter für RenderStream an, der im folgenden Beispiel fett dargestellt wird:

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

Der Encoderfilter unterstützt möglicherweise IAMVideoCompression oder andere Schnittstellen zum Festlegen der Codierungsparameter. Eine Liste der möglichen Schnittstellen finden Sie unter Dateicodierungs- und Decodierungsschnittstellen.

Aufzeichnen von Videos in einer Datei