使用影片編解碼器私人資料 (Microsoft Media Foundation)
Windows Media Video 9 編解碼器所產生的壓縮輸出無法正確解壓縮,而不需要編碼器提供的某些資料。 此資料稱為編解碼器私用資料,必須附加至輸出媒體類型。 您可以呼叫 IWMCodecPrivateData 介面的 方法來取得編解碼器私用資料。 將其他完整的 DMO_MEDIA_TYPE 結構傳遞至 IWMCodecPrivateData::SetPartialOutputType。 然後呼叫 IWMCodecPrivateData::GetPrivateData 兩次,一次取得資料的大小,然後再呼叫一次將資料複製到該大小的緩衝區。 建立新的緩衝區,以保存附加私人資料的 VIDEOINFOHEADER 結構,並將結構和資料複製到該緩衝區。 最後,將DMO_MEDIA_TYPE結構的pbFormat成員設定為新建立緩衝區的位址,並將cbFormat成員設定為VIDEOINFOHEADER和私用資料的合併大小,以位元組為單位。
如果您使用 MediaFoundation,您可以呼叫MFCreateAMMediaTypeFromMFMediaType,從IMFMediaType介面建構DMO_MEDIA_TYPE結構。
您必須先在編碼器上設定屬性之後,使用取得的編解碼器私用資料。 如果有任何屬性變更,您必須取得新的私人資料。 如果您未使用在編碼會話設定所有屬性之後取得的私人資料,解碼器可能無法解壓縮資料。
下列程式碼範例示範如何取得視訊類型的私人資料:
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;
}
注意
視訊編碼器所傳遞的編解碼器私用資料不保證與相同組態的不同編解碼器實作所傳遞的私人資料相同。 您必須一律使用本主題中的步驟來產生此值;絕對不要從另一個檔案複製私人資料。
相關主題