使用媒体缓冲区 (Microsoft Media Foundation)
本主题介绍如何使用 IMFMediaBuffer 接口访问媒体缓冲区中的数据。 所有媒体缓冲区都公开 IMFMediaBuffer,该缓冲区专为任何类型的数据而设计。 未压缩的视频帧是一种特殊情况,如主题 “未压缩的视频缓冲区”中所述。
缓冲区大小
媒体缓冲区有两个与之关联的大小:
最大长度是为缓冲区分配的内存的物理大小。 此值是在创建缓冲区时设置的,在缓冲区的生存期内不会更改。 最大长度指示可以存储在缓冲区中的数据量。 若要查找最大大小,请调用 IMFMediaBuffer::GetMaxLength。
当前长度是当前在缓冲区中的有效数据量。 首次分配缓冲区时,当前长度为零,因为缓冲区中没有有效的数据。 如果将任何数据写入缓冲区,则必须通过调用 IMFMediaBuffer::SetCurrentLength 来更新当前长度。 例如,如果将 100 字节的数据写入缓冲区,请使用值 100 调用 SetCurrentLength 。 如果从媒体缓冲区读取数据,请调用 IMFMediaBuffer::GetCurrentLength 来找出缓冲区中当前的数据量。 不要读过当前长度。 当前长度永远不能超过缓冲区的最大长度。
访问缓冲区内存
若要访问缓冲区中的内存,请调用 IMFMediaBuffer::Lock。 此方法返回指向内存块开头的指针。 它还返回最大长度和当前长度。 使用完指针后,调用 IMFMediaBuffer::Unlock。
将数据写入媒体缓冲区:
- 调用 IMFMediaBuffer::Lock 以获取指向内存的指针。 该方法还返回缓冲区的最大长度。
- 将数据写入内存中,最大长度为缓冲区的最大长度。
- 调用 IMFMediaBuffer::SetCurrentLength 以更新当前长度。 将当前长度设置为与在步骤 2 中写入的数据量相等。
- 调用 IMFMediaBuffer::Unlock 以解锁缓冲区。
从媒体缓冲区读取数据:
- 调用 IMFMediaBuffer::Lock 以获取指向内存的指针。 该方法还返回缓冲区的当前长度 (缓冲区) 的有效数据量。
- 读取内存的内容,最大为当前长度。
- 调用 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;
}
相关主题