Konfigurieren des Videoausgabeformats
[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]
Hinweis
Die in diesem Thema beschriebene Funktionalität ist veraltet. Zum Konfigurieren des Ausgabeformats eines Erfassungsgeräts sollte eine Anwendung die AM_MEDIA_TYPE Struktur verwenden, die von IAMStreamConfig::GetFormat im pmt-Parameter zurückgegeben wird.
Ein Aufnahmegerät kann eine Reihe von Ausgabeformaten unterstützen. Beispielsweise kann ein Gerät 16-Bit-RGB, 32-Bit-RGB und YUYV unterstützen. In jedem dieser Formate kann das Gerät eine Reihe von Framegrößen unterstützen.
Auf einem WDM-Gerät wird die IAMStreamConfig-Schnittstelle verwendet, um zu melden, welche Formate das Gerät unterstützt, und um das Format festzulegen. (Verwenden Sie für ältere VFW-Geräte das Dialogfeld Videoformat VFW, wie unter Anzeigen von VFW-Erfassungsdialogfeldern beschrieben.) Die IAMStreamConfig-Schnittstelle wird für den Aufnahme-Pin, den Vorschau-Pin oder beides des Erfassungsfilters verfügbar gemacht. Verwenden Sie die ICaptureGraphBuilder2::FindInterface-Methode , um den Schnittstellenzeiger abzurufen:
IAMStreamConfig *pConfig = NULL;
hr = pBuild->FindInterface(
&PIN_CATEGORY_PREVIEW, // Preview pin.
0, // Any media type.
pCap, // Pointer to the capture filter.
IID_IAMStreamConfig, (void**)&pConfig);
Das Gerät verfügt über eine Liste von Medientypen, die es unterstützt. Für jeden Medientyp bietet das Gerät auch eine Reihe von Funktionen. Dazu gehören der Bereich der Framegrößen, die für dieses Format verfügbar sind, wie gut das Gerät das Bild strecken oder verkleinern kann, und den Bereich der Bildfrequenzen.
Rufen Sie die IAMStreamConfig::GetNumberOfCapabilities-Methode auf, um die Anzahl der Medientypen abzurufen. Die -Methode gibt zwei Werte zurück:
- Die Anzahl der Medientypen.
- Die Größe der Struktur, die die Funktionsinformationen enthält.
Der Größenwert ist erforderlich, da die IAMStreamConfig-Schnittstelle sowohl für Audio als auch für Video verwendet wird (und auf andere Medientypen erweitert werden kann). Für Videos werden die Funktionen mithilfe der VIDEO_STREAM_CONFIG_CAPS-Struktur beschrieben, während audio die AUDIO_STREAM_CONFIG_CAPS-Struktur verwendet.
Um die Medientypen aufzulisten, rufen Sie die IAMStreamConfig::GetStreamCaps-Methode mit einem nullbasierten Index auf. Die GetStreamCaps-Methode gibt einen Medientyp und die entsprechende Funktionsstruktur zurück:
int iCount = 0, iSize = 0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
// Check the size to make sure we pass in the correct structure.
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
{
// Use the video capabilities structure.
for (int iFormat = 0; iFormat < iCount; iFormat++)
{
VIDEO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE *pmtConfig;
hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
if (SUCCEEDED(hr))
{
/* Examine the format, and possibly use it. */
// Delete the media type when you are done.
DeleteMediaType(pmtConfig);
}
}
Beachten Sie, wie die Strukturen für die GetStreamCaps-Methode zugeordnet werden. Die -Methode ordnet die Medientypstruktur zu, während der Aufrufer die Funktionsstruktur zuordnet. Koerieren Sie die Funktionsstruktur in einen Bytearrayzeiger. Nachdem Sie mit dem Medientyp fertig sind, löschen Sie die AM_MEDIA_TYPE-Struktur zusammen mit dem Formatblock des Medientyps.
Sie können das Gerät so konfigurieren, dass es ein Format verwendet, das in der GetStreamCaps-Methode zurückgegeben wird. Rufen Sie einfach IAMStreamConfig::SetFormat mit dem Medientyp auf:
hr = pConfig->SetFormat(pmtConfig);
Wenn der Pin nicht verbunden ist, versucht er, dieses Format zu verwenden, wenn er eine Verbindung herstellt. Wenn der Pin bereits verbunden ist, wird versucht, die Verbindung mithilfe des neuen Formats wiederherzustellen. In beiden Fällen ist es möglich, dass der nachgeschaltete Filter das Format ablehnt.
Sie können den Medientyp auch ändern, bevor Sie ihn an die SetFormat-Methode übergeben. Hier kommt die VIDEO_STREAM_CONFIG_CAPS-Struktur ins Ziel. Es beschreibt alle gültigen Möglichkeiten zum Ändern des Medientyps. Um diese Informationen verwenden zu können, müssen Sie die Details dieses bestimmten Medientyps verstehen.
Angenommen, GetStreamCaps gibt ein 24-Bit-RGB-Format mit einer Framegröße von 320 x 240 Pixel zurück. Sie können diese Informationen abrufen, indem Sie den Haupttyp, Untertyp und Formatblock des Medientyps untersuchen:
if ((pmtConfig.majortype == MEDIATYPE_Video) &&
(pmtConfig.subtype == MEDIASUBTYPE_RGB24) &&
(pmtConfig.formattype == FORMAT_VideoInfo) &&
(pmtConfig.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
(pmtConfig.pbFormat != NULL))
{
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig.pbFormat;
// pVih contains the detailed format information.
LONG lWidth = pVih->bmiHeader.biWidth;
LONG lHeight = pVih->bmiHeader.biHeight;
}
Die VIDEO_STREAM_CONFIG_CAPS-Struktur gibt die minimale und maximale Breite und Höhe an, die für diesen Medientyp verwendet werden kann. Außerdem erhalten Sie die "Schrittgröße", die die Inkremente definiert, um die Sie die Breite oder Höhe anpassen können. Das Gerät kann beispielsweise Folgendes zurückgeben:
- MinOutputSize: 160 x 120
- MaxOutputSize: 320 x 240
- OutputGranularityX: 8 Pixel (horizontale Schrittgröße)
- OutputGranularityY: 8 Pixel (vertikale Schrittgröße)
Angesichts dieser Zahlen könnten Sie die Breite auf alles im Bereich (160, 168, 176, ... 304, 312, 320) und die Höhe zu allem im Bereich (120, 128, 136, ... 104, 112, 120). Dieser Prozess wird anhand des folgenden Diagramms veranschaulicht.
Um eine neue Framegröße festzulegen, ändern Sie direkt die in GetStreamCaps zurückgegebene AM_MEDIA_TYPE-Struktur:
pVih->bmiHeader.biWidth = 160;
pVih->bmiHeader.biHeight = 120;
pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);
Übergeben Sie dann den Medientyp wie zuvor beschrieben an die SetFormat-Methode .
Die Elemente MinFrameInterval und MaxFrameInterval von VIDEO_STREAM_CONFIG_CAPS sind die minimale und maximale Länge jedes Videoframes, die Sie wie folgt in Bildfrequenzen übersetzen können:
frames per second = 10,000,000 / frame duration
Um eine bestimmte Bildfrequenz anzufordern, ändern Sie den Wert von AvgTimePerFrame in der Struktur VIDEOINFOHEADER oder VIDEOINFOHEADER2 im Medientyp. Das Gerät unterstützt möglicherweise nicht jeden möglichen Wert zwischen dem Minimum und dem Maximum, sodass der Treiber den nächstgelegenen Wert verwendet. Um zu sehen, welchen Wert der Treiber tatsächlich verwendet hat, rufen Sie IAMStreamConfig::GetFormat auf, nachdem Sie SetFormat aufgerufen haben.
Einige Treiber melden möglicherweise MAXLONGLONG ( 0x7FFFFFFFFFFFFFFF) für den Wert von MaxFrameInterval, was bedeutet, dass es keine maximale Dauer gibt. Möglicherweise möchten Sie jedoch eine Minimale Bildfrequenz in Ihrer Anwendung erzwingen, z. B. 1 fps.