Condividi tramite


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.

 

Configurazione della codifica video

Uso dei video