メディア バッファーの操作 (Microsoft Media Foundation)
このトピックでは、 IMFMediaBuffer インターフェイスを使用してメディア バッファー内のデータにアクセスする方法について説明します。 すべてのメディア バッファーは、あらゆる種類のデータ用に設計された IMFMediaBuffer を公開します。 圧縮されていないビデオ フレームは、トピック 「圧縮されていないビデオ バッファー」で説明されている特殊なケースです。
バッファー サイズ
メディア バッファーには、次の 2 つのサイズが関連付けられています。
最大長は、バッファーに割り当てられるメモリの物理サイズです。 この値は、バッファーの作成時に設定され、バッファーの有効期間中は変更されません。 最大長は、バッファーに格納できるデータの量を示します。 最大サイズを見つけるには、 IMFMediaBuffer::GetMaxLength を呼び出します。
現在の長さは、現在バッファー内にある有効なデータの量です。 バッファーが最初に割り当てられると、バッファーに有効なデータがないため、現在の長さは 0 になります。 バッファーにデータを書き込む場合は、 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 ポインターを返します。 メディア バッファーの参照カウントが 0 に達し、オブジェクトが破棄されると、メモリが自動的に解放されます。
次の例は、システム メモリ バッファーを作成し、バッファーに書き込む方法を示しています。
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;
}
関連トピック