共用方式為


使用媒體緩衝區 (Microsoft Media Foundation)

本主題描述如何使用 IMFMediaBuffer 介面來存取媒體緩衝區中的數據。 所有媒體緩衝區都會公開 IMFMediaBuffer,這是針對任何類型的數據所設計。 未壓縮的視訊畫面是特殊案例,如 未壓縮的視訊緩衝區主題所述,

緩衝區大小

媒體緩衝區有兩個與其相關聯的尺寸。

  • 最大長度 為緩衝區配置的記憶體物理大小。 當緩衝區建立且不會在緩衝區存留期間變更時,就會設定此值。 最大長度表示可以儲存在緩衝區中的數據量。 若要尋找大小上限,請呼叫 IMFMediaBuffer::GetMaxLength

  • 目前長度 是目前在緩衝區中的有效數據量。 第一次配置緩衝區時,目前的長度為零,因為緩衝區中沒有有效的數據。 如果您將任何數據寫入緩衝區,您必須呼叫 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 來解除鎖定緩衝區。

建立系統記憶體緩衝區

系統記憶體緩衝區是管理系統記憶體區塊的媒體緩衝區。 若要建立此對象的實例,請呼叫 MFCreateMemoryBufferMFCreateAlignedMemoryBuffer 並指定緩衝區大小。 這兩個函式都會配置記憶體區塊,並傳回 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;
}

媒體緩衝區

Media Foundation Platform API