Utilisation de données privées de codec vidéo (Microsoft Media Foundation)
La sortie compressée produite par les codecs Windows Media Video 9 ne peut pas être correctement décompressée sans certaines données fournies par l’encodeur. Ces données, appelées données privées de codec, doivent être ajoutées au type de support de sortie. Vous pouvez obtenir les données privées du codec en appelant les méthodes de l’interface IWMCodecPrivateData . Transmettez la structure DMO_MEDIA_TYPE par ailleurs complète à IWMCodecPrivateData::SetPartialOutputType. Appelez ensuite IWMCodecPrivateData::GetPrivateData deux fois, une fois pour obtenir la taille des données, puis à nouveau pour copier les données dans une mémoire tampon de cette taille. Créez une mémoire tampon pour contenir la structure VIDEOINFOHEADER avec les données privées ajoutées, puis copiez la structure et les données dans cette mémoire tampon. Enfin, définissez le membre pbFormat de la structure DMO_MEDIA_TYPE sur l’adresse du tampon nouvellement créé et définissez le membre cbFormat sur la taille combinée, en octets, des données VIDEOINFOHEADER et privées.
Si vous utilisez MediaFoundation, vous pouvez construire une structure DMO_MEDIA_TYPE à partir d’une interface IMFMediaType en appelant MFCreateAMMediaTypeFromMFMediaType.
Vous devez utiliser les données privées de codec obtenues après avoir défini les propriétés sur l’encodeur. Si des propriétés sont modifiées, vous devez obtenir de nouvelles données privées. Si vous n’utilisez pas les données privées obtenues une fois que toutes les propriétés sont définies pour la session d’encodage, le décodeur peut ne pas être en mesure de décompresser les données.
L’exemple de code suivant montre comment obtenir les données privées pour un type de vidéo :
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;
}
Notes
Il n’est pas garanti que les données privées de codec fournies par un encodeur vidéo soient identiques aux données privées fournies par une implémentation différente du même codec pour la même configuration. Vous devez toujours générer cette valeur à l’aide des étapes décrites dans cette rubrique ; ne copiez jamais les données privées d’un autre fichier.
Rubriques connexes