演示文稿描述符
演示文稿是共享常见演示时间的一组相关媒体流。 例如,演示文稿可能包含来自电影的音频和视频流。 演示文稿描述符是包含特定演示文稿说明的对象。 演示文稿描述符用于配置媒体源和某些媒体接收器。
每个演示文稿描述符都包含一个或多个 流描述符的列表。 它们描述了演示文稿中的流。 可以选择或取消选择流。 只有所选流才会生成数据。 取消选择的流不处于活动状态,不会生成任何数据。 每个流描述符都有一个 媒体类型处理程序,用于更改流的媒体类型或获取流的当前媒体类型。 (有关媒体类型的详细信息,请参阅 媒体类型。)
下表显示了其中每个对象公开的主接口。
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);
相关主题