Schreiben eines Projekts in eine Datei
[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde durch MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation ersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code nach Möglichkeit MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet. Microsoft schlägt vor, vorhandenen Code, der die Legacy-APIs verwendet, um nach Möglichkeit die neuen APIs zu verwenden.]
[Diese API wird nicht unterstützt und kann in Zukunft geändert oder nicht mehr verfügbar sein.]
In diesem Artikel wird beschrieben, wie Sie ein DirectShow Editing Services-Projekt in eine Datei schreiben. Zunächst wird beschrieben, wie eine Datei mit der grundlegenden Render-Engine geschrieben wird. Anschließend wird die intelligente Neukomprimierung mit der intelligenten Render-Engine beschrieben.
Eine Übersicht darüber, wie DirectShow Editing Services Projekte rendert, finden Sie unter Informationen zu den Render-Engines.
Verwenden der Basic-Render-Engine
Erstellen Sie zunächst das Front-End des Diagramms wie folgt:
- Erstellen Sie die Render-Engine.
- Geben Sie die Zeitleiste an.
- Legen Sie den Renderbereich fest. (Optional)
- Erstellen Sie das Front-End des Diagramms.
Im folgenden Codebeispiel werden diese Schritte veranschaulicht.
IRenderEngine *pRender = NULL;
hr = CoCreateInstance(CLSID_RenderEngine, NULL, CLSCTX_INPROC,
IID_IRenderEngine, (void**) &pRender);
hr = pRender->SetTimelineObject(pTL);
hr = pRender->ConnectFrontEnd( );
Fügen Sie als Nächstes dem Filterdiagramm Multiplexer- und Dateischreibfilter hinzu. Dies ist am einfachsten mit dem Capture Graph Builder zu tun, einer DirectShow-Komponente zum Erstellen von Erfassungsdiagrammen. Der Capture Graph Builder macht die ICaptureGraphBuilder2-Schnittstelle verfügbar. Führen Sie die folgenden Schritte aus:
- Erstellen Sie eine instance des Capture Graph Builders.
- Rufen Sie einen Zeiger auf das Diagramm ab, und übergeben Sie ihn an den Graphen-Generator.
- Geben Sie den Namen und den Medientyp der Ausgabedatei an. Dieser Schritt erhält auch einen Zeiger auf den Muxfilter, der später erforderlich ist.
Im folgenden Codebeispiel werden diese Schritte veranschaulicht.
CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **)&pBuilder);
// Get a pointer to the graph front end.
IGraphBuilder *pGraph;
pRender->GetFilterGraph(&pGraph);
pBuilder->SetFiltergraph(pGraph);
// Create the file-writing section.
IBaseFilter *pMux;
pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,
OLESTR("Output.avi"), &pMux, NULL);
Schließen Sie schließlich die Ausgabepins am Front-End an den Mux-Filter an.
- Ruft die Anzahl der Gruppen ab.
- Rufen Sie für jeden Pin einen Zeiger auf den Pin ab.
- Erstellen Sie optional eine instance eines Komprimierungsfilters, um den Stream zu komprimieren. Der Typ des Kompressors hängt vom Medientyp der Gruppe ab. Sie können den Systemgeräte-Enumerator verwenden, um die verfügbaren Komprimierungsfilter aufzulisten. Weitere Informationen finden Sie unter Auflisten von Geräten und Filtern.
- Legen Sie optional Komprimierungsparameter wie die Key-Frame-Rate fest. Dieser Schritt wird weiter unten im Artikel ausführlich erläutert.
- Rufen Sie ICaptureGraphBuilder2::RenderStream auf. Diese Methode verwendet Zeiger auf den Pin, den Komprimierungsfilter (falls vorhanden) und den Multiplexer.
Im folgenden Codebeispiel wird gezeigt, wie die Ausgabepins verbunden werden.
long NumGroups;
pTimeline->GetGroupCount(&NumGroups);
// Loop through the groups and get the output pins.
for (i = 0; i < NumGroups; i++)
{
IPin *pPin;
if (pRender->GetGroupOutputPin(i, &pPin) == S_OK)
{
IBaseFilter *pCompressor;
// Create a compressor filter. (Not shown.)
// Set compression parameters. (Not shown.)
// Connect the pin.
pBuilder->RenderStream(NULL, NULL, pPin, pCompressor, pMux);
pCompressor->Release();
pPin->Release();
}
}
Verwenden Sie zum Festlegen von Komprimierungsparametern (zuvor Schritt 4) die IAMVideoCompression-Schnittstelle . Diese Schnittstelle wird auf den Ausgabepins von Komprimierungsfiltern verfügbar gemacht. Führen Sie die Pins des Komprimierungsfilters auf, und fragen Sie jeden Ausgabepin für IAMVideoCompression ab. (Informationen zum Aufzählen von Pins finden Sie unter Aufzählen von Pins.) Stellen Sie sicher, dass Sie alle Schnittstellenzeiger freigeben, die Sie während dieses Schritts abgerufen haben.
Nachdem Sie das Filterdiagramm erstellt haben, rufen Sie die IMediaControl::Run-Methode für den Filterdiagramm-Manager auf. Während das Filterdiagramm ausgeführt wird, werden die Daten in eine Datei geschrieben. Verwenden Sie ereignisbenachrichtigungen, um auf den Abschluss der Wiedergabe zu warten. (Siehe Reagieren auf Ereignisse.) Wenn die Wiedergabe abgeschlossen ist, müssen Sie explizit IMediaControl::Stop aufrufen, um das Filterdiagramm zu beenden. Andernfalls wird die Datei nicht ordnungsgemäß geschrieben.
Verwenden der Smart Render Engine
Um die Vorteile der intelligenten Neukomprimierung zu nutzen, verwenden Sie die intelligente Render-Engine anstelle der grundlegenden Render-Engine. Die Schritte beim Erstellen des Diagramms sind nahezu identisch. Der Hauptunterschied besteht darin, dass die Komprimierung im Front-End des Diagramms behandelt wird, nicht im Abschnitt zum Schreiben von Dateien.
Wichtig
Verwenden Sie die Intelligente Render-Engine nicht zum Lesen oder Schreiben von Windows Media-Dateien.
Jede Videogruppe verfügt über eine Eigenschaft, die das Komprimierungsformat für diese Gruppe angibt. Das Komprimierungsformat muss genau mit dem nicht komprimierten Format der Gruppe in Höhe, Breite, Bittiefe und Bildfrequenz übereinstimmen. Die Engine für intelligentes Rendern verwendet das Komprimierungsformat, wenn sie das Diagramm erstellt. Bevor Sie das Komprimierungsformat festlegen, müssen Sie das nicht komprimierte Format für diese Gruppe festlegen, indem Sie IAMTimelineGroup::SetMediaType aufrufen.
Um das Komprimierungsformat einer Gruppe festzulegen, rufen Sie die IAMTimelineGroup::SetSmartRecompressFormat-Methode auf. Diese Methode verwendet einen Zeiger auf eine SCompFmt0-Struktur . Die SCompFmt0-Struktur verfügt über zwei Member: nFormatId, die null sein muss, und MediaType, eine AM_MEDIA_TYPE-Struktur . Initialisieren Sie die AM_MEDIA_TYPE-Struktur mit den Formatinformationen.
Hinweis
Wenn das endgültige Projekt das gleiche Format wie eine Ihrer Quelldateien haben soll, können Sie die AM_MEDIA_TYPE-Struktur direkt aus der Quelldatei abrufen, indem Sie den Mediendetektor verwenden. Siehe IMediaDet::get_StreamMediaType.
Wandeln Sie die Variable SCompFmt0 in einen Zeiger vom Typ long um, wie im folgenden Beispiel gezeigt.
SCompFmt0 *pFormat = new SCompFmt0;
memset(pFormat, 0, sizeof(SCompFmt0));
pFormat->nFormatId = 0;
// Initialize pFormat->MediaType. (Not shown.)
pGroup->SetSmartRecompressFormat( (long*) pFormat );
Die Intelligente Render-Engine sucht automatisch nach einem kompatiblen Komprimierungsfilter. Sie können auch einen Komprimierungsfilter für eine Gruppe angeben, indem Sie ISmartRenderEngine::SetGroupCompressor aufrufen.
Führen Sie zum Erstellen des Graphen die gleichen Schritte aus, die für die Basic Render Engine im vorherigen Abschnitt beschrieben wurden. Die einzigen Unterschiede sind die folgenden:
- Verwenden Sie die Intelligente Render-Engine, nicht die einfache Render-Engine. Der Klassenbezeichner ist CLSID_SmartRenderEngine.
- Legen Sie komprimierungsparameter fest, nachdem Sie das Front-End erstellt haben, aber bevor Sie die Ausgabepins rendern. Rufen Sie die ISmartRenderEngine::GetGroupCompressor-Methode auf, um einen Zeiger auf den Komprimierungsfilter einer Gruppe abzurufen. Fragen Sie dann wie zuvor beschrieben die IAMVideoCompression-Schnittstelle ab.
- Wenn Sie die Ausgabepins rendern, muss kein Komprimierungsfilter eingefügt werden. Der Stream ist bereits komprimiert.
Zugehörige Themen