Uso de datos privados de códec de vídeo (Microsoft Media Foundation)
La salida comprimida producida por los códecs de Windows Media Video 9 no se puede descomprimir correctamente sin algunos datos proporcionados por el codificador. Estos datos, denominados datos privados de códec, deben anexarse al tipo de medio de salida. Puede obtener los datos privados del códec llamando a los métodos de la interfaz IWMCodecPrivateData . De lo contrario, pase la estructura de DMO_MEDIA_TYPE completa a IWMCodecPrivateData::SetPartialOutputType. A continuación, llame a IWMCodecPrivateData::GetPrivateData dos veces, una vez para obtener el tamaño de los datos y, a continuación, vuelva a copiar los datos en un búfer de ese tamaño. Cree un nuevo búfer para contener la estructura VIDEOINFOHEADER con los datos privados anexados y copie la estructura y los datos en ese búfer. Por último, establezca el miembro pbFormat de la estructura de DMO_MEDIA_TYPE en la dirección del búfer recién creado y establezca el miembro cbFormat en el tamaño combinado, en bytes, de VIDEOINFOHEADER y de los datos privados.
Si usa MediaFoundation, puede construir una estructura de DMO_MEDIA_TYPE a partir de una interfaz IMFMediaType llamando a MFCreateAMMediaTypeFromMFMediaType.
Debe usar los datos privados del códec obtenidos después de establecer primero las propiedades en el codificador. Si se cambian las propiedades, debe obtener nuevos datos privados. Si no usa los datos privados obtenidos después de establecer todas las propiedades para la sesión de codificación, es posible que el descodificador no pueda descomprimir los datos.
En el ejemplo de código siguiente se muestra cómo obtener los datos privados de un tipo de vídeo:
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;
}
Nota
No se garantiza que los datos privados del códec entregados por un codificador de vídeo sean los mismos que los datos privados entregados por una implementación diferente del mismo códec para la misma configuración. Siempre debe generar este valor mediante los pasos descritos en este tema; nunca copie los datos privados de otro archivo.
Temas relacionados