Поделиться через


Использование частных данных Видеокодека (Microsoft Media Foundation)

Сжатые выходные данные, созданные кодеками Windows Media Video 9, нельзя правильно распаковывать без некоторых данных, предоставляемых кодировщиком. Эти данные, называемые закрытыми данными codec, должны быть добавлены к типу выходного носителя. Частные данные кодека можно получить, вызвав методы интерфейса IWMCodecPrivateData. При условии, что структура DMO_MEDIA_TYPE является полной, передайте её в IWMCodecPrivateData::SetPartialOutputType. Затем вызовите IWMCodecPrivateData::GetPrivateData дважды, чтобы получить размер данных, а затем снова скопировать данные в буфер этого размера. Создайте новый буфер для хранения структуры VIDEOINFOHEADER с добавленными частными данными, а также скопируйте структуру и данные в этот буфер. Наконец, установите элемент pbFormat структуры DMO_MEDIA_TYPE на адрес только что созданного буфера и задайте элемент cbFormat равным объединенному размеру в байтах для VIDEOINFOHEADER и данных частного сектора.

При использовании MediaFoundation можно создать структуру DMO_MEDIA_TYPE из интерфейса IMFMediaType путем вызова MFCreateAMMediaTypeFromMFMediaType.

Вы должны использовать частные данные кодека, полученные после первого задания свойств кодировщика. При изменении каких-либо свойств необходимо получить новые частные данные. Если вы не используете частные данные, полученные после установки всех свойств для сеанса кодирования, декодатор может не сможет распаковывать данные.

В следующем примере кода показано, как получить частные данные для типа видео:

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;
}

Заметка

Приватные данные кодека, предоставляемые кодировщиком видео, не гарантируется, что они будут такими же, как и данные, предоставляемые другой реализацией того же кодека для той же конфигурации. Это значение всегда необходимо создать, выполнив действия, описанные в этом разделе; никогда не копируйте частные данные из другого файла.

 

настройка кодирования видео

работа с видео