Video Codec Özel Verilerini Kullanma (Microsoft Media Foundation)

Windows Media Video 9 codec'leri tarafından üretilen sıkıştırılmış çıkış, kodlayıcı tarafından sağlanan bazı veriler olmadan düzgün bir şekilde çözülemez. Codec özel verileri olarak adlandırılan bu verilerin çıkış medya türüne eklenmesi gerekir. IWMCodecPrivateData arabiriminin yöntemlerini çağırarak codec özel verilerini alabilirsiniz. Aksi takdirde DMO_MEDIA_TYPE yapısını IWMCodecPrivateData::SetPartialOutputType'a tam olarak geçirin. Ardından IWMCodecPrivateData::GetPrivateData iki kez çağırarak verilerin boyutunu alın ve sonra verileri bu boyutta bir arabelleğe yeniden kopyalayın. Özel verilerin eklendiği VIDEOINFOHEADER yapısını tutmak için yeni bir arabellek oluşturun ve yapıyı ve verileri bu arabelleğe kopyalayın. Son olarak, DMO_MEDIA_TYPE yapısının pbFormat üyesini yeni oluşturulan arabelleğin adresine ayarlayın ve cbFormat üyesini VIDEOINFOHEADER ve özel verilerin bayt cinsinden birleşik boyutuna ayarlayın.

MediaFoundation kullanıyorsanız, MFCreateAMMediaTypeFromMFMediaTypeçağırarak BIR IMFMediaType arabiriminden bir DMO_MEDIA_TYPE yapısı oluşturabilirsiniz.

Kodlayıcıda özellikleri ayarladıktan sonra alınan codec özel verilerini kullanmanız gerekir. Herhangi bir özellik değiştirilirse, yeni özel veriler almanız gerekir. Kodlama oturumu için tüm özellikler ayarlandıktan sonra elde edilen özel verileri kullanmazsanız, kod çözücü verilerin sıkıştırmasını kaldıramayabilir.

Aşağıdaki kod örneği, bir video türü için özel verilerin nasıl alınduğunu gösterir:

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

Not

Bir video kodlayıcı tarafından teslim edilen codec özel verilerinin, aynı yapılandırma için aynı codec bileşeninin farklı bir uygulaması tarafından sunulan özel veriyle aynı olması garanti değildir. Bu konudaki adımları kullanarak her zaman bu değeri oluşturmalısınız; özel verileri asla başka bir dosyadan kopyalamayın.

 

Video Kodlamayı Yapılandırma

Video ile Çalışma