Usando dados privados de codec de vídeo (Microsoft Media Foundation)

A saída compactada produzida pelos codecs Windows Media Video 9 não pode ser descompactada corretamente sem alguns dados fornecidos pelo codificador. Esses dados, chamados dados particulares de codec, devem ser anexados ao tipo de mídia de saída. Você pode obter os dados particulares do codec chamando os métodos da interface IWMCodecPrivateData. Passe a estrutura DMO _ MEDIA _ TYPE para IWMCodecPrivateData::SetPartialOutputType. Em seguida, chame IWMCodecPrivateData::GetPrivateData duas vezes, uma vez para obter o tamanho dos dados e, em seguida, novamente para copiar os dados para um buffer desse tamanho. Crie um novo buffer para manter a estrutura VIDEOINFOHEADER com os dados privados anexados e copie a estrutura e os dados para esse buffer. Por fim, de definir o membro pbFormat da estrutura DMO MEDIA _ _ TYPE como o endereço do buffer recém-criado e de definir o membro cbFormat para o tamanho combinado, em bytes, do VIDEOINFOHEADER e dos dados privados.

Se você estiver usando MediaFoundation, poderá construir uma estrutura DMO _ MEDIA _ TYPE de uma interface IMFMediaType chamando MFCreateAMMediaTypeFromMFMediaType.

Você deve usar os dados particulares do codec obtidos após a primeira configuração das propriedades no codificador. Se alguma propriedade for alterada, você deverá obter novos dados privados. Se você não usar os dados privados obtidos depois que todas as propriedades são definidas para a sessão de codificação, o decodificador pode não conseguir descompactar os dados.

O exemplo de código a seguir demonstra como obter os dados privados para um tipo de vídeo:

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

Observação

Não há garantia de que os dados particulares do codec fornecidos por um codificador de vídeo sejam iguais aos dados privados fornecidos por uma implementação diferente do mesmo codec para a mesma configuração. Você sempre deve gerar esse valor usando as etapas neste tópico; nunca copie os dados privados de outro arquivo.

Configurando a codificação de vídeo

Trabalhando com vídeo