다음을 통해 공유


미디어 버퍼 작업(Microsoft Media Foundation)

이 항목에서는 IMFMediaBuffer 인터페이스를 사용하여 미디어 버퍼의 데이터에 액세스하는 방법을 설명합니다. 모든 미디어 버퍼는 모든 유형의 데이터를 위해 설계된 IMFMediaBuffer를 노출합니다. 압축되지 않은 비디오 프레임은 압축되지 않은 비디오 버퍼 항목에 설명된 특별한 경우입니다.

버퍼 크기

미디어 버퍼에는 두 가지 크기가 연결되어 있습니다.

  • 최대 길이는 버퍼에 할당된 메모리의 실제 크기입니다. 이 값은 버퍼를 만들 때 설정되며 버퍼의 수명 동안 변경되지 않습니다. 최대 길이는 버퍼에 저장할 수 있는 데이터의 양을 나타냅니다. 최대 크기를 찾으려면 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를 호출하여 버퍼의 잠금을 해제합니다.

시스템 메모리 버퍼 만들기

시스템 메모리 버퍼는 시스템 메모리 블록을 관리하는 미디어 버퍼입니다. 이 개체의 instance 만들려면 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 플랫폼 API