Utilisation de données privées de codec vidéo (Microsoft Media Foundation)
la sortie compressée générée par les codecs Windows Media Video 9 ne peut pas être décompressée correctement sans que des données soient fournies par l’encodeur. Ces données, appelées données privées du codec, doivent être ajoutées au type de média de sortie. Vous pouvez récupérer les données privées du codec en appelant les méthodes de l’interface IWMCodecPrivateData . transmettez le DMO la structure du _ _ TYPE de média à IWMCodecPrivateData :: SetPartialOutputType. Appelez ensuite IWMCodecPrivateData :: GetPrivateData à deux reprises, une fois pour obtenir la taille des données, puis de nouveau pour copier les données dans une mémoire tampon de cette taille. Créez une mémoire tampon destinée à 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 de _ _ TYPE de média DMO sur l’adresse de la mémoire tampon nouvellement créée et définissez le membre cbFormat sur la taille combinée, en octets, du VIDEOINFOHEADER et des données privées.
si vous utilisez MediaFoundation, vous pouvez construire une structure de _ _ TYPE de média DMO à partir d’une interface IMFMediaType en appelant MFCreateAMMediaTypeFromMFMediaType.
Vous devez utiliser les données privées du codec obtenues après avoir défini les propriétés sur l’encodeur. Si des propriétés sont modifiées, vous devez vous procurer de nouvelles données privées. Si vous n’utilisez pas les données privées obtenues après que toutes les propriétés ont été définies pour la session d’encodage, le décodeur risque de ne pas pouvoir décompresser les données.
L’exemple de code suivant montre comment obtenir les données privées d’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 du codec fournies par un encodeur vidéo soient les mêmes que celles 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.