Schritt 4. Festlegen von Allocator-Eigenschaften
[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.]
Dies ist Schritt 4 des Tutorials Schreiben von Transformationsfiltern.
Hinweis
Dieser Schritt ist für Filter, die von CTransInPlaceFilter abgeleitet werden, nicht erforderlich.
Nachdem sich zwei Pins auf einen Medientyp einigen, wählen sie eine Zuweisung für die Verbindung aus und verhandeln Zuweisungseigenschaften, z. B. die Puffergröße und die Anzahl der Puffer.
In der CTransformFilter-Klasse gibt es zwei Zuweisungen: einen für die Upstream-Pinverbindung und einen für die Downstream-Pinverbindung. Der Upstream Filter wählt die Upstream Zuweisung und auch die Zuweisungseigenschaften aus. Der Eingabenadel akzeptiert, was der Upstream Filter entscheidet. Wenn Sie dieses Verhalten ändern müssen, überschreiben Sie die CBaseInputPin::NotifyAllocator-Methode .
Der Ausgabepin des Transformationsfilters wählt die nachgeschaltete Zuweisung aus. Sie führt die folgenden Schritte aus:
- Wenn der Downstreamfilter eine Zuweisung bereitstellen kann, verwendet der Ausgabepin diesen. Andernfalls erstellt der Ausgabepin eine neue Zuweisung.
- Der Ausgabepin ruft die Zuweisungsanforderungen des Downstreamfilters (falls vorhanden) durch Aufrufen von IMemInputPin::GetAllocatorRequirements ab.
- Der Ausgabepin ruft die CTransformFilter::D ecideBufferSize-Methode des Transformationsfilters auf, die rein virtuell ist. Die Parameter auf diese Methode sind ein Zeiger auf die Zuweisung und eine ALLOCATOR_PROPERTIES-Struktur mit den Anforderungen des downstream-Filters. Wenn für den downstream-Filter keine Zuweisungsanforderungen gelten, wird die Struktur auf Null gesetzt.
- In der DecideBufferSize-Methode legt die abgeleitete Klasse die Allocatoreigenschaften durch Aufrufen von IMemAllocator::SetProperties fest.
Im Allgemeinen wählt die abgeleitete Klasse die Zuordnungseigenschaften basierend auf dem Ausgabeformat, den Anforderungen des Downstreamfilters und den eigenen Anforderungen des Filters aus. Versuchen Sie, Eigenschaften auszuwählen, die mit der Anforderung des Downstreamfilters kompatibel sind. Andernfalls kann der Downstreamfilter die Verbindung ablehnen.
Im folgenden Beispiel legt der RLE-Encoder Mindestwerte für Puffergröße, Pufferausrichtung und Pufferanzahl fest. Für das Präfix wird ein beliebiger Wert verwendet, den der downstream-Filter angefordert hat. Das Präfix ist in der Regel null Bytes, aber einige Filter erfordern es. Der AVI Mux-Filter verwendet beispielsweise das Präfix, um RIFF-Header zu schreiben.
HRESULT CRleFilter::DecideBufferSize(
IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp)
{
AM_MEDIA_TYPE mt;
HRESULT hr = m_pOutput->ConnectionMediaType(&mt);
if (FAILED(hr))
{
return hr;
}
ASSERT(mt.formattype == FORMAT_VideoInfo);
BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);
pProp->cbBuffer = DIBSIZE(*pbmi) * 2;
if (pProp->cbAlign == 0)
{
pProp->cbAlign = 1;
}
if (pProp->cBuffers == 0)
{
pProp->cBuffers = 1;
}
// Release the format block.
FreeMediaType(mt);
// Set allocator properties.
ALLOCATOR_PROPERTIES Actual;
hr = pAlloc->SetProperties(pProp, &Actual);
if (FAILED(hr))
{
return hr;
}
// Even when it succeeds, check the actual result.
if (pProp->cbBuffer > Actual.cbBuffer)
{
return E_FAIL;
}
return S_OK;
}
Die Zuweisung kann möglicherweise nicht genau mit Ihrer Anforderung übereinstimmen. Daher gibt die SetProperties-Methode das tatsächliche Ergebnis in einer separaten ALLOCATOR_PROPERTIES-Struktur zurück (der Actual-Parameter im vorherigen Beispiel). Selbst wenn SetProperties erfolgreich ist, sollten Sie das Ergebnis überprüfen, um sicherzustellen, dass es die Mindestanforderungen Ihres Filters erfüllt.
Benutzerdefinierte Zuweisungen
Standardmäßig verwenden alle Filterklassen die CMemAllocator-Klasse für ihre Zuweisungen. Diese Klasse ordnet Arbeitsspeicher aus dem virtuellen Adressraum des Clientprozesses zu (mit VirtualAlloc). Wenn Ihr Filter eine andere Art von Arbeitsspeicher verwenden muss, z. B. DirectDraw-Oberflächen, können Sie eine benutzerdefinierte Zuweisung implementieren. Sie können die CBaseAllocator-Klasse verwenden oder eine völlig neue Zuweisungsklasse schreiben. Wenn Ihr Filter über eine benutzerdefinierte Zuweisung verfügt, überschreiben Sie die folgenden Methoden, je nachdem, welcher Pin die Zuweisung verwendet:
- Eingabenadel: CBaseInputPin::GetAllocator und CBaseInputPin::NotifyAllocator.
- Ausgabepin: CBaseOutputPin::D ecideAllocator.
Wenn der andere Filter die Verbindung mit Ihrer benutzerdefinierten Zuweisung ablehnt, kann der Filter entweder die Verbindung nicht herstellen oder eine Verbindung mit der Zuweisung des anderen Filters herstellen. Im letzteren Fall müssen Sie möglicherweise ein internes Flag festlegen, das den Typ der Zuweisung angibt. Ein Beispiel für diesen Ansatz finden Sie unter CDrawImage-Klasse.
Weiter: Schritt 5. Transformieren Sie das Bild.
Zugehörige Themen