비디오 코덱 프라이빗 데이터 사용(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;
}
참고
비디오 인코더에서 제공하는 코덱 프라이빗 데이터는 동일한 구성에 대해 동일한 코덱의 다른 구현에서 제공하는 프라이빗 데이터와 동일하지 않습니다. 이 항목의 단계를 사용하여 항상 이 값을 생성해야 합니다. 다른 파일에서 프라이빗 데이터를 복사하지 않습니다.
관련 항목