Uso dei buffer multimediali (Microsoft Media Foundation)

In questo argomento viene descritto come utilizzare l'interfaccia IMFMediaBuffer per accedere ai dati in un buffer multimediale. Tutti i buffer multimediali espongono IMFMediaBuffer, progettato per qualsiasi tipo di dati. I fotogrammi video non compressi sono un caso speciale, descritto nell'argomento Buffer video non compressi.

Dimensione buffer

A un buffer multimediale sono associate due dimensioni:

  • La lunghezza massima è la dimensione fisica della memoria allocata per il buffer. Questo valore viene impostato quando viene creato il buffer e non cambia durante la durata del buffer. La lunghezza massima indica la quantità di dati che è possibile archiviare nel buffer. Per trovare le dimensioni massime, chiamare IMFMediaBuffer::GetMaxLength.

  • La lunghezza corrente è la quantità di dati validi attualmente presenti nel buffer. Quando il buffer viene allocato per la prima volta, la lunghezza corrente è zero, perché nel buffer non sono presenti dati validi. Se si scrivono dati nel buffer, è necessario aggiornare la lunghezza corrente chiamando IMFMediaBuffer::SetCurrentLength. Ad esempio, se si scrivono 100 byte di dati nel buffer, chiamare SetCurrentLength con il valore 100. Se si leggono dati da un buffer multimediale, chiamare IMFMediaBuffer::GetCurrentLength per scoprire quanti dati sono attualmente presenti nel buffer. Non leggere oltre la lunghezza corrente. La lunghezza corrente non può mai superare la lunghezza massima del buffer.

Accesso alla memoria buffer

Per accedere alla memoria nel buffer, chiamare IMFMediaBuffer::Lock. Questo metodo restituisce un puntatore all'inizio del blocco di memoria. Restituisce anche la lunghezza massima e la lunghezza corrente. Al termine dell'uso del puntatore, chiamare IMFMediaBuffer::Unlock.

Per scrivere dati in un buffer multimediale:

  1. Chiamare IMFMediaBuffer::Lock per ottenere un puntatore alla memoria. Il metodo restituisce anche la lunghezza massima del buffer.
  2. Scrivere i dati nella memoria, fino alla lunghezza massima del buffer.
  3. Chiamare IMFMediaBuffer::SetCurrentLength per aggiornare la lunghezza corrente. Impostare la lunghezza corrente uguale alla quantità di dati scritti nel passaggio 2.
  4. Chiama IMFMediaBuffer::Unlock per sbloccare il buffer.

Per leggere i dati da un buffer multimediale:

  1. Chiamare IMFMediaBuffer::Lock per ottenere un puntatore alla memoria. Il metodo restituisce anche la lunghezza corrente del buffer (la quantità di dati validi nel buffer).
  2. Leggere il contenuto della memoria, fino alla lunghezza corrente.
  3. Chiama IMFMediaBuffer::Unlock per sbloccare il buffer.

Creazione di buffer di memoria di sistema

Il buffer di memoria di sistema è un buffer multimediale che gestisce un blocco di memoria di sistema. Per creare un'istanza di questo oggetto, chiamare MFCreateMemoryBuffer o MFCreateAlignedMemoryBuffer e specificare una dimensione del buffer. Entrambe le funzioni allocano un blocco di memoria e restituiscono un puntatore IMFMediaBuffer . La memoria viene rilasciata automaticamente quando il conteggio dei riferimenti del buffer multimediale raggiunge zero e l'oggetto viene eliminato definitivamente.

Nell'esempio seguente viene illustrato come creare un buffer di memoria di sistema e scrivere nel 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;
}

Buffer multimediali

API della piattaforma Media Foundation