メディア バッファーの操作 (Microsoft Media Foundation)

このトピックでは、 IMFMediaBuffer インターフェイスを使用してメディア バッファー内のデータにアクセスする方法について説明します。 すべてのメディア バッファーは、あらゆる種類のデータ用に設計された IMFMediaBuffer を公開します。 圧縮されていないビデオ フレームは、トピック 「圧縮されていないビデオ バッファー」で説明されている特殊なケースです。

バッファー サイズ

メディア バッファーには、次の 2 つのサイズが関連付けられています。

  • 最大長は、バッファーに割り当てられるメモリの物理サイズです。 この値は、バッファーの作成時に設定され、バッファーの有効期間中は変更されません。 最大長は、バッファーに格納できるデータの量を示します。 最大サイズを見つけるには、 IMFMediaBuffer::GetMaxLength を呼び出します。

  • 現在の長さは、現在バッファー内にある有効なデータの量です。 バッファーが最初に割り当てられると、バッファーに有効なデータがないため、現在の長さは 0 になります。 バッファーにデータを書き込む場合は、 IMFMediaBuffer::SetCurrentLength を呼び出して現在の長さを更新する必要があります。 たとえば、バッファーに 100 バイトのデータを書き込む場合は、値 100 で SetCurrentLength を呼び出します。 メディア バッファーからデータを読み取る場合は、 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 ポインターを返します。 メディア バッファーの参照カウントが 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;
}

メディア バッファー

Media Foundation Platform API