演示文稿描述符

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

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

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

Object 接口
演示文稿描述符 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);

媒体源

Media Foundation 平台 API