演示文稿描述符

演示文稿 是一组共享常见演示时间的相关媒体流。 例如,演示文稿可能包含电影中的音频和视频流。 演示文稿描述符 是包含特定演示文稿说明的对象。 演示描述符用于配置媒体源和某些媒体接收器。

每个演示文稿描述符都包含一个或多个 流描述符的列表。 这些描述演示文稿中的流。 可以选择或取消选择流。 只有所选流才会生成数据。 未选择的流不处于活动状态,并且不生成任何数据。 每个流描述符都有一个 媒体类型处理程序,该处理程序用于更改流的媒体类型或获取流的当前媒体类型。 (有关媒体类型的详细信息,请参阅 媒体类型。)

下表显示了其中每个对象公开的主要接口。

对象 接口
演示文稿描述符 IMFPresentationDescriptor
流描述符 IMFStreamDescriptor
媒体类型处理程序 IMFMediaTypeHandler

 

媒体源演示文稿

每个媒体源都提供一个演示描述符,描述源的默认配置。 在默认配置中,至少选择了一个流,并且每个选定的流都具有媒体类型。 若要获取演示描述符,请调用 IMFMediaSource::CreatePresentationDescriptor。 该方法返回 IMFPresentationDescriptor 指针。

可以修改源的演示文稿描述符以选择一组不同的流。 除非媒体源停止,否则不要修改演示文稿描述符。 调用 IMFMediaSource::Start 启动源时,将应用更改。

若要获取流数,请调用 IMFPresentationDescriptor::GetStreamDescriptorCount。 若要获取流的流描述符,请调用 IMFPresentationDescriptor::GetStreamDescriptorByIndex 并传入流的索引。 流从零开始编制索引。 GetStreamDescriptorByIndex 方法返回 IMFStreamDescriptor 指针。 它还返回一个布尔标志,指示是否选择了流。 如果选择流,媒体源将生成该流的数据。 否则,源不会为该流生成任何数据。 若要选择流,请使用流的索引调用 IMFPresentationDescriptor::SelectStream。 若要取消选择流,请调用 IMFPresentationDescriptor::D eselectStream

以下代码演示如何从媒体源获取演示文稿描述符并枚举流。

HRESULT hr = S_OK;
DWORD cStreams = 0;
BOOL  fSelected = FALSE;

IMFPresentationDescriptor *pPresentation = NULL;
IMFStreamDescriptor *pStreamDesc = NULL;

hr = pSource->CreatePresentationDescriptor(&pPresentation);

if (SUCCEEDED(hr))
{
    hr = pPresentation->GetStreamDescriptorCount(&cStreams);
}

if (SUCCEEDED(hr))
{
    for (DWORD iStream = 0; iStream < cStreams; iStream++)
    {
        hr = pPresentation->GetStreamDescriptorByIndex(
            iStream, &fSelected, &pStreamDesc);

        if (FAILED(hr))
        {
            break;
        }

        /*  Use the stream descriptor. (Not shown.) */

        SAFE_RELEASE(pStreamDesc);
    }
}
SAFE_RELEASE(pPresentation);
SAFE_RELEASE(pStreamDesc);

媒体类型处理程序

若要更改流的媒体类型或获取流的当前媒体类型,请使用流描述符的媒体类型处理程序。 调用 IMFStreamDescriptor::GetMediaTypeHandler 以获取媒体类型处理程序。 此方法返回 IMFMediaTypeHandler 指针。

如果只想了解流中的数据类型(如音频或视频),请调用 IMFMediaTypeHandler::GetMajorType。 此方法返回主要媒体类型的 GUID。 例如,播放应用程序通常将音频流连接到音频呈现器,并将视频流连接到视频呈现器。 如果使用媒体会话或拓扑加载程序生成拓扑,则主要类型 GUID 可能是所需的唯一格式信息。

如果应用程序需要有关当前格式的更多详细信息,请调用 IMFMediaTypeHandler::GetCurrentMediaType。 此方法返回指向媒体类型的 IMFMediaType 接口的指针。 使用此接口获取格式的详细信息。

媒体类型处理程序还包含流支持的媒体类型列表。 若要获取列表的大小,请调用 IMFMediaTypeHandler::GetMediaTypeCount。 若要从列表中获取媒体类型,请使用媒体类型的索引调用 IMFMediaTypeHandler::GetMediaTypeByIndex。 媒体类型按首选项的大致顺序返回。 例如,对于音频格式,首选更高的采样率而不是较低的采样率。 但是,没有明确的规则可以控制排序,因此你应该简单地将其视为一个准则。

支持的类型列表可能不包含流支持的每个可能的媒体类型。 若要测试是否支持特定媒体类型,请调用 IMFMediaTypeHandler::IsMediaTypeSupported。 若要设置媒体类型,请调用 IMFMediaTypeHandler::SetCurrentMediaType。 如果方法成功,流将包含符合指定格式的数据。 SetCurrentMediaType 方法不会更改首选类型的列表。

以下代码演示如何获取媒体类型处理程序、枚举首选媒体类型并设置媒体类型。 此示例假定应用程序有一些算法(此处未显示)用于选择媒体类型。 具体细节在很大程度上取决于应用程序。

HRESULT hr = S_OK;
DWORD cTypes = 0;
BOOL  bTypeOK = FALSE;

IMFMediaTypeHandler *pHandler = NULL;
IMFMediaType *pMediaType = NULL;

hr = pStreamDesc->GetMediaTypeHandler(&pHandler);

if (SUCCEEDED(hr))
{
    hr = pHandler->GetMediaTypeCount(&cTypes);
}

if (SUCCEEDED(hr))
{
    for (DWORD iType = 0; iType < cTypes; iType++)
    {   
        hr = pHandler->GetMediaTypeByIndex(iType, &pMediaType);

        if (FAILED(hr))
        {
            break;
        }

        /* Examine the media type. (Not shown.)  */

        /* If this media type is acceptable, set the media type. */

        if (bTypeOK)
        {
            hr = pHandler->SetCurrentMediaType(pMediaType);
            break;
        }

        SAFE_RELEASE(pMediaType);
    }
}    

SAFE_RELEASE(pMediaType);
SAFE_RELEASE(pHandler);

媒体源

媒体基础平台 API