Работа с буферами мультимедиа (Microsoft Media Foundation)

В этом разделе описывается использование интерфейса IMFMediaBuffer для доступа к данным в буфере мультимедиа. Все буферы мультимедиа предоставляют функции IMFMediaBuffer, предназначенные для любых типов данных. Несжатые видеокадры — это особый случай, описанный в разделе Несжатые видео буферы.

Размер буфера

Буфер мультимедиа имеет два связанных размера:

  • Максимальная длина — это физический размер памяти, выделенной для буфера. Это значение задается при создании буфера и не изменяется в течение времени существования буфера. Максимальная длина указывает, сколько данных может храниться в буфере. Чтобы найти максимальный размер, вызовите IMFMediaBuffer::GetMaxLength.

  • Текущая длина — это объем допустимых данных, которые в настоящее время находятся в буфере. При первом выделении буфера текущая длина равна нулю, так как в буфере нет допустимых данных. При записи данных в буфер необходимо обновить текущую длину, вызвав IMFMediaBuffer::SetCurrentLength. Например, если вы записываете в буфер 100 байт данных, вызовите Метод SetCurrentLength со значением 100. Если вы считываете данные из буфера мультимедиа, вызовите IMFMediaBuffer::GetCurrentLength , чтобы узнать, сколько данных в данный момент находится в буфере. Не считывать данные за текущую длину. Текущая длина никогда не может превышать максимальную длину буфера.

Доступ к буферной памяти

Чтобы получить доступ к памяти в буфере, вызовите IMFMediaBuffer::Lock. Этот метод возвращает указатель на начало блока памяти. Он также возвращает максимальную и текущую длину. Завершив работу с указателем, вызовите IMFMediaBuffer::Unlock.

Чтобы записать данные в буфер мультимедиа, выполните приведенные далее действия.

  1. Вызовите IMFMediaBuffer::Lock , чтобы получить указатель на память. Метод также возвращает максимальную длину буфера.
  2. Запишите данные в память до максимальной длины буфера.
  3. Вызовите IMFMediaBuffer::SetCurrentLength , чтобы обновить текущую длину. Задайте текущую длину, равную объему данных, которые вы написали на шаге 2.
  4. Вызовите IMFMediaBuffer::Unlock , чтобы разблокировать буфер.

Чтение данных из буфера мультимедиа:

  1. Вызовите IMFMediaBuffer::Lock , чтобы получить указатель на память. Метод также возвращает текущую длину буфера (объем допустимых данных в буфере).
  2. Считывает содержимое памяти до текущей длины.
  3. Вызовите IMFMediaBuffer::Unlock , чтобы разблокировать буфер.

Создание буферов системной памяти

Буфер системной памяти — это буфер мультимедиа, который управляет блоком системной памяти. Чтобы создать экземпляр этого объекта, вызовите MFCreateMemoryBuffer или MFCreateAlignedMemoryBuffer и укажите размер буфера. Обе функции выделяют блок памяти и возвращают указатель IMFMediaBuffer . Память автоматически освобождается, когда количество ссылок буфера мультимедиа достигает нуля и объект уничтожается.

В следующем примере показано, как создать системный буфер памяти и выполнить запись в буфер.

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

Буферы мультимедиа

API-интерфейсы платформы Media Foundation