Verwenden privater Videocodecdaten (Microsoft Media Foundation)
Die komprimierte Ausgabe, die von den Windows Media Video 9-Codecs erzeugt wird, kann ohne einige Vom Encoder bereitgestellte Daten nicht ordnungsgemäß dekomprimiert werden. Diese Daten, die als private Codecdaten bezeichnet werden, müssen an den Ausgabemedientyp angefügt werden. Sie können die privaten Codecdaten abrufen, indem Sie die Methoden der IWMCodecPrivateData-Schnittstelle aufrufen. Übergeben Sie die ansonsten vollständige DMO_MEDIA_TYPE-Struktur an IWMCodecPrivateData::SetPartialOutputType. Rufen Sie dann IWMCodecPrivateData::GetPrivateData zweimal auf, einmal, um die Größe der Daten abzurufen, und dann erneut, um die Daten in einen Puffer dieser Größe zu kopieren. Erstellen Sie einen neuen Puffer, um die VIDEOINFOHEADER-Struktur mit angefügten privaten Daten aufzunehmen, und kopieren Sie die Struktur und die Daten in diesen Puffer. Legen Sie schließlich den pbFormat-Member der DMO_MEDIA_TYPE-Struktur auf die Adresse des neu erstellten Puffers fest, und legen Sie den cbFormat-Member auf die kombinierte Größe des VIDEOINFOHEADER und der privaten Daten in Bytes fest.
Wenn Sie MediaFoundation verwenden, können Sie eine DMO_MEDIA_TYPE-Struktur über eine IMFMediaType-Schnittstelle erstellen, indem Sie MFCreateAMMediaTypeFromMFMediaType aufrufen.
Sie müssen die privaten Codecdaten verwenden, die nach dem ersten Festlegen der Eigenschaften für den Encoder abgerufen werden. Wenn Eigenschaften geändert werden, müssen Sie neue private Daten abrufen. Wenn Sie die privaten Daten nicht verwenden, nachdem alle Eigenschaften für die Codierungssitzung festgelegt wurden, kann der Decoder die Daten möglicherweise nicht dekomprimieren.
Im folgenden Codebeispiel wird veranschaulicht, wie Sie die privaten Daten für einen Videotyp abrufen:
HRESULT GetFinalOutputType(DMO_MEDIA_TYPE* pMedia, IMediaObject* pDMO)
{
// WARNING //
// This function does not deallocate the memory pointed to by
// pMedia->pbFormat. If the VIDEOINFOHEADER referenced by pbFormat
// was dynamically allocated, a reference to it must be kept before
// calling this function so that it can be freed.
// Perform simple parameter checks.
if(pMedia == NULL || pDMO == NULL)
return E_POINTER;
if(pMedia->formattype != MEDIATYPE_VideoInfo)
return E_INVALIDARG;
HRESULT hr = S_OK;
IWMCodecPrivateData* pPrivData = NULL;
BYTE* pbData = NULL;
DWORD cbData = 0;
BYTE* pbNewVidInf = NULL;
DWORD cbNewVidInf = 0;
BYTE* pbNewPriv = NULL;
// Get the private data interface.
hr = pDMO->QueryInterface(IID_IWMCodecPrivateData,
(void**)&pPrivData);
GOTO_EXIT_IF_FAILED(hr);
// Set the partial media type.
hr = pPrivData->SetPartialOutputType(pMedia);
GOTO_EXIT_IF_FAILED(hr);
// Get the size of the private data.
hr = pPrivData->GetPrivateData(NULL, &cbData);
GOTO_EXIT_IF_FAILED(hr);
// Allocate memory for the private data.
pbData = new BYTE[cbData];
if(pbData == NULL)
{
hr = E_OUTOFMEMORY;
goto Exit:
}
// Get the private data.
hr = pPrivData->GetPrivateData(pbData, &cbData);
// Allocate memory for the new VIDEOINFOHEADER.
cbNewVidInf = pMedia->cbFormat + cbData;
pbNewVidInf = new BYTE[cbNewVidInf];
// Copy the VIDEOINFOHEADER to the new buffer.
memcpy((void*)pbNewVidInf, (void*)pMedia->pbFormat, pMedia->cbFormat);
// Get the address of the first byte following the VIDEOINFOHEADER.
pbNewPriv = pbNewVidInf + pMedia->cbFormat;
// Copy the private data to the new buffer.
memcpy((void*)pbNewPriv, (void*)pbData, cbData);
// Set the new VIDEOINFOHEADER in the DMO_MEDIA_TYPE.
pMedia->pbFormat = pbNewVidInf;
pMedia->cbFormat = cbNewVidInf;
Exit:
SAFE_RELEASE(pPrivData);
SAFE_ARRAY_DELETE(pbData);
pbNewPriv = NULL;
return hr;
}
Hinweis
Die von einem Videoencoder bereitgestellten privaten Codecdaten sind nicht garantiert mit den privaten Daten identisch, die von einer anderen Implementierung desselben Codecs für dieselbe Konfiguration bereitgestellt werden. Sie müssen diesen Wert immer mithilfe der Schritte in diesem Thema generieren. Kopieren Sie die privaten Daten niemals aus einer anderen Datei.