Trabalhando com buffers de mídia (Microsoft Media Foundation)

Este tópico descreve como usar a interface IMFMediaBuffer para acessar os dados em um buffer de mídia. Todos os buffers de mídia expõem IMFMediaBuffer, que foi projetado para qualquer tipo de dados. Quadros de vídeo não compactados são um caso especial, descrito no tópico Buffers de Vídeo Descompactados.

Tamanho do Buffer

Um buffer de mídia tem dois tamanhos associados a ele:

  • O comprimento máximo é o tamanho físico da memória alocada para o buffer. Esse valor é definido quando o buffer é criado e não é alterado durante o tempo de vida do buffer. O comprimento máximo indica quantos dados podem ser armazenados no buffer. Para encontrar o tamanho máximo, chame IMFMediaBuffer::GetMaxLength.

  • O comprimento atual é a quantidade de dados válidos que está atualmente no buffer. Quando o buffer é alocado pela primeira vez, o comprimento atual é zero, porque não há dados válidos no buffer. Se você gravar dados no buffer, deverá atualizar o comprimento atual chamando IMFMediaBuffer::SetCurrentLength. Por exemplo, se você gravar 100 bytes de dados no buffer, chame SetCurrentLength com o valor 100. Se você ler dados de um buffer de mídia, chame IMFMediaBuffer::GetCurrentLength para descobrir quantos dados estão atualmente no buffer. Não leia além do comprimento atual. O comprimento atual nunca pode exceder o comprimento máximo do buffer.

Acessando a memória do buffer

Para acessar a memória no buffer, chame IMFMediaBuffer::Lock. Esse método retorna um ponteiro para o início do bloco de memória. Ele também retorna o comprimento máximo e o comprimento atual. Quando terminar de usar o ponteiro, chame IMFMediaBuffer::Unlock.

Para gravar dados em um buffer de mídia:

  1. Chame IMFMediaBuffer::Lock para obter um ponteiro para a memória. O método também retorna o comprimento máximo do buffer.
  2. Escreva seus dados na memória até o comprimento máximo do buffer.
  3. Chame IMFMediaBuffer::SetCurrentLength para atualizar o comprimento atual. Defina o comprimento atual igual à quantidade de dados que você escreveu na etapa 2.
  4. Chame IMFMediaBuffer::Unlock para desbloquear o buffer.

Para ler dados de um buffer de mídia:

  1. Chame IMFMediaBuffer::Lock para obter um ponteiro para a memória. O método também retorna o comprimento atual do buffer (a quantidade de dados válidos no buffer).
  2. Leia o conteúdo da memória até o comprimento atual.
  3. Chame IMFMediaBuffer::Unlock para desbloquear o buffer.

Criando buffers de memória do sistema

O buffer de memória do sistema é um buffer de mídia que gerencia um bloco de memória do sistema. Para criar uma instância desse objeto, chame MFCreateMemoryBuffer ou MFCreateAlignedMemoryBuffer e especifique um tamanho de buffer. Ambas as funções alocam um bloco de memória e retornam um ponteiro IMFMediaBuffer . A memória é liberada automaticamente quando a contagem de referência do buffer de mídia atinge zero e o objeto é destruído.

O exemplo a seguir mostra como criar um buffer de memória do sistema e gravar no buffer.

HRESULT CreateSystemMemoryBuffer(
    BYTE *pSrc, 
    DWORD cbData, 
    IMFMediaBuffer **ppBuffer
    )
{
    HRESULT hr = S_OK;
    BYTE *pData = NULL;

    IMFMediaBuffer *pBuffer = NULL;

    // Create the media buffer.
    hr = MFCreateMemoryBuffer(
        cbData,   // Amount of memory to allocate, in bytes.
        &pBuffer        
        );

    // Lock the buffer to get a pointer to the memory.
    if (SUCCEEDED(hr))
    {
        hr = pBuffer->Lock(&pData, NULL, NULL);
    }

    if (SUCCEEDED(hr))
    {
        memcpy_s(pData, cbData, pSrc, cbData);
    }

    // Update the current length.
    if (SUCCEEDED(hr))
    {
        hr = pBuffer->SetCurrentLength(cbData);
    }

    // Unlock the buffer.
    if (pData)
    {
        hr = pBuffer->Unlock();
    }

    if (SUCCEEDED(hr))
    {
        *ppBuffer = pBuffer;
        (*ppBuffer)->AddRef();
    }

    return hr;
}

Buffers de mídia

Media Foundation Platform APIs