Uso di dati privati codec video (Microsoft Media Foundation)
L'output compresso prodotto dai codec Windows Media Video 9 non può essere decompresso correttamente senza alcuni dati forniti dal codificatore. Questi dati, denominati dati privati codec, devono essere aggiunti al tipo di supporto di output. È possibile ottenere i dati privati del codec chiamando i metodi dell'interfaccia IWMCodecPrivateData . Passare la struttura DMO_MEDIA_TYPE completa in caso contrario a IWMCodecPrivateData::SetPartialOutputType. Chiama quindi IWMCodecPrivateData::GetPrivateData due volte, una volta per ottenere le dimensioni dei dati e quindi di nuovo per copiare i dati in un buffer di tale dimensione. Creare un nuovo buffer per contenere la struttura VIDEOINFOHEADER con i dati privati aggiunti e copiare la struttura e i dati in tale buffer. Impostare infine il membro pbFormat della struttura DMO_MEDIA_TYPE sull'indirizzo del buffer appena creato e impostare il membro cbFormat sulla dimensione combinata, in byte, di VIDEOINFOHEADER e dei dati privati.
Se si usa MediaFoundation, è possibile costruire una struttura DMO_MEDIA_TYPE da un'interfaccia IMFMediaType chiamando MFCreateAMMediaTypeFromMFMediaType.
È necessario usare i dati privati codec ottenuti dopo la prima impostazione delle proprietà nel codificatore. Se vengono modificate proprietà, è necessario ottenere nuovi dati privati. Se non si usano i dati privati ottenuti dopo l'impostazione di tutte le proprietà per la sessione di codifica, il decodificatore potrebbe non essere in grado di decomprimere i dati.
L'esempio di codice seguente illustra come ottenere i dati privati per un tipo di video:
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
I dati privati codec recapitati da un codificatore video non sono necessariamente gli stessi dei dati privati recapitati da un'implementazione diversa dello stesso codec per la stessa configurazione. È sempre necessario generare questo valore seguendo la procedura descritta in questo argomento; non copiare mai i dati privati da un altro file.
Argomenti correlati