使用媒体示例

本主题介绍如何使用 IMFSample 接口操控媒体示例对象。 有关媒体示例的一般概述,请参阅媒体示例

若要创建新的媒体示例,请调用 MFCreateSample 函数。 最初,示例的缓冲区列表为空。 若要将一个缓冲区添加到列表末尾,请调用 IMFSample::AddBuffer

以下代码演示如何创建示例并向其添加缓冲区。

HRESULT CreateMediaSample(DWORD cbData, IMFSample **ppSample)
{
    HRESULT hr = S_OK;

    IMFSample *pSample = NULL;
    IMFMediaBuffer *pBuffer = NULL;

    hr = MFCreateSample(&pSample);

    if (SUCCEEDED(hr))
    {
        hr = MFCreateMemoryBuffer(cbData, &pBuffer);
    }

    if (SUCCEEDED(hr))
    {
        hr = pSample->AddBuffer(pBuffer);
    }

    if (SUCCEEDED(hr))
    {
        *ppSample = pSample;
        (*ppSample)->AddRef();
    }

    SafeRelease(&pSample);
    SafeRelease(&pBuffer);
    return hr;
}

从示例中获取缓冲区的建议方法是调用 IMFSample::ConvertToContiguousBuffer。 此方法将返回单个连续缓冲区。

若要循环访问列表中的缓冲区,请首先调用 IMFSample::GetBufferCount。 此方法将返回缓冲区数。 然后,调用 IMFSample::GetBufferByIndex 并指定要检索的缓冲区的索引。 在编制缓冲区索引时,将从零开始。

以下代码演示如何循环访问示例中的缓冲区。

IMFMediaBuffer *pBuffer = NULL;
DWORD cBuffers = 0;

hr = pSample->GetBufferCount(&cBuffers);

if (SUCCEEDED(hr))
{
    for (DWORD i = 0; i < cBuffers; i++)
    {
        hr = pSample->GetBufferByIndex(i, &pBuffer);

        // Use buffer (not shown).

        SafeRelease(&pBuffer);

        if (FAILED(hr))
        {
            break;
        }
    }
}

示例具有时间戳和持续时间。 时间戳指示应呈现样本中的数据的时间(相对于演示时钟的相对时间)。 持续时间是应呈现数据的时间长度。 通常,生成数据的组件将设置初始时间戳和持续时间。 媒体会话可能会修改这些值。 若要设置时间戳,请调用 IMFSample::SetSampleTime。 若要设置持续时间,请调用 IMFSample::SetSampleDuration

示例还可以具有属性,其中包含有关该示例的其他信息。 有关示例属性的列表,请参阅示例属性。 若要设置和检索属性,请使用 IMFSample 继承的 IMFAttributes 接口

媒体示例

媒体缓冲区