使用顺序器源
本主题介绍如何使用顺序器源。 它包含下列部分:
有关顺序器源的一般概述,请参阅关于顺序器源。
概述
顺序器源公开以下接口。
接口 | 说明 |
---|---|
IMFMediaSource | 公开通用媒体源功能。 |
IMFSequencerSource | 可让应用程序添加或删除拓扑。 |
IMFMediaSourceTopologyProvider | 检索在媒体会话上排队的下一个拓扑。 |
IMFMediaSourcePresentationProvider | 媒体会话用于结束段。 应用程序不使用此接口。 |
IMFGetService | 查询 服务接口的顺序器源。 |
若要播放媒体源序列,请执行以下步骤:
- 若要创建顺序器源,请调用 MFCreateSequencerSource 函数。
- 对于每个段,请创建一个播放拓扑,如创建播放拓扑中所述。 若要将拓扑添加到演示文稿,请调用 IMFSequencerSource::AppendTopology。
- 在开始播放之前,请在顺序器源上调用 IMFMediaSource::CreatePresentationDescriptor。 此方法返回指向第一段的演示文稿描述符的指针。 若要获取与此段关联的拓扑,请在 IMFMediaSourceTopologyProvider 接口的顺序器源上调用 QueryInterface。 将演示文稿描述符传递给 IMFMediaSourceTopologyProvider::GetMediaSourceTopology 方法。 此方法返回指向拓扑的指针。
- 通过调用媒体会话的 IMFMediaSession::SetTopology 方法,将第一段的拓扑传递给媒体会话。
- 调用 IMFMediaSession::Start 以开始播放。
- 当顺序器源准备好预注册下一段时,它会发送其事件数据为 IMFPresentationDescriptor 接口指针的 MENewPresentation 事件。 同样,通过在顺序器源上调用 GetMediaSourceTopology,并通过调用 SetTopology 在媒体会话上设置拓扑,以获取段的拓扑。 不需要重新启动媒体源;它将自动播放到下一段。
- 在应用程序退出之前,通过调用 IMFMediaSource::Shutdown 关闭顺序器源。
以下代码演示如何获取拓扑并在媒体会话上设置它:
// Queues the next topology on the session.
HRESULT CPlaylist::QueueNextSegment(IMFPresentationDescriptor *pPD)
{
IMFMediaSourceTopologyProvider *pTopoProvider = NULL;
IMFTopology *pTopology = NULL;
//Get the topology for the presentation descriptor
HRESULT hr = m_pSequencerSource->QueryInterface(IID_PPV_ARGS(&pTopoProvider));
if (FAILED(hr))
{
goto done;
}
hr = pTopoProvider->GetMediaSourceTopology(pPD, &pTopology);
if (FAILED(hr))
{
goto done;
}
//Set the topology on the media session
m_pSession->SetTopology(NULL, pTopology);
done:
SafeRelease(&pTopoProvider);
SafeRelease(&pTopology);
return hr;
}
有关完整的代码示例,请参阅顺序器源示例代码。
添加拓扑
顺序器源维护两个拓扑列表:输入列表和预注册列表。
输入列表是对应于播放列表段的拓扑集合,按照应用程序通过调用 IMFSequencerSource::AppendTopology 添加拓扑的顺序。 此方法为每个拓扑分配类型 MFSequencerElementId 的唯一段标识符。 段标识符设置为所有源拓扑节点的属性。 应用程序可以使用 MF_TOPONODE_SEQUENCE_ELEMENTID 属性从源节点获取段标识符。 如果应用程序多次在同一拓扑上调用 AppendTopology,则输入列表可以具有重复的拓扑;但是,它们通过唯一的段标识符进行标识。
预注册列表是已初始化的输入列表拓扑的集合,用于准备播放。 这可让媒体会话在活动拓扑结束时无缝地过渡到下一个拓扑。 应用程序无法直接从预注册列表中添加或删除拓扑;从输入列表中选择用于播放的拓扑时,顺序器源会生成它。 这会导致顺序器源将输入列表中的下一个拓扑添加到预注册列表。 执行此操作后,顺序器源会异步引发 MENewPresentation 事件,并将预注册拓扑的表示描述符作为事件数据传递。 应用程序必须使用媒体会话的 IMFMediaEventGenerator 接口侦听此事件,并通过调用 IMFMediaSession::SetTopology 将预注册拓扑排入媒体会话队列。 必须在媒体会话完成活动拓扑的播放之前完成此操作。 SetTopology 向媒体会话告知必须在播放活动拓扑结束后播放的下一个拓扑。 为确保无缝转换,应用程序必须在媒体会话完成播放以前的拓扑之前调用 SetTopology。 否则,段之间会有间隙。
只要活动的拓扑后面有拓扑,就会引发 MENewPresentation 事件。 因此,如果输入列表仅包含一个拓扑,或者活动拓扑是输入列表中的最后一个拓扑,则不会引发此事件。
预注册列表与输入列表同步,每次在输入列表中添加或删除拓扑时刷新。
删除拓扑
若要从顺序器源中删除拓扑,应用程序必须调用 IMFSequencerSource::DeleteTopology 方法并指定段标识符。
在调用 DeleteTopology 之前,应用程序必须确保媒体会话不使用应用程序要删除的拓扑。 为此,在应用程序调用 DeleteTopology 之前,必须执行以下两项操作:
为拓扑接收具有 MF_TOPOSTATUS_ENDED 的 MESessionTopologyStatus 事件,以确保媒体会话已完成播放。
为下一个拓扑接收明有 MF_TOPOSTATUS_STARTED_SOURCE 的 MESessionTopologyStatus,以确保媒体会话已开始播放下一个拓扑,并接收 MESessionEnded 事件,以确保媒体会话使用顺序源中的最后一个拓扑完成。
如果删除的段是活动的拓扑,则停止播放,顺序器源将引发 MEEndOfPresentationSegment 事件。 如果活动的拓扑也是最后一个拓扑,则会引发 MEEndOfPresentation 事件。
跳到段
应用程序可以通过启动具有段偏移量的媒体会话,跳到序列中的特定段,如下所示:
调用 MFCreateSequencerSegmentOffset 函数以创建段偏移量。 在 dwId 参数中指定段的标识符。 (首次将拓扑添加到顺序器源时,IMFSequencerSource::AppendTopology 方法返回了标识符。)hnsOffset 参数指定相对于段开始的时间偏移量。 此时将开始播放。 对于 pvarSegmentOffset 参数,传入空 PROPVARIANT 的地址。 函数返回时,此 PROPVARIANT 包含段偏移量。
在媒体会话上调用 IMFMediaSession::Start 方法。 对于 pguidTimeFormat 参数,请使用 GUID 值MF_TIME_FORMAT_SEGMENT_OFFSET。 此值表示按段偏移量查找。 对于 pvarStartPosition 参数,传递上一步创建的 PROPVARIANT 的地址。
下面的代码示例演示如何跳到序列中指定段的开头。
// Skips to the specified segment in the sequencer source
HRESULT CPlaylist::SkipTo(DWORD index)
{
if (index >= m_count)
{
return E_INVALIDARG;
}
MFSequencerElementId ID = m_segments[index].SegmentID;
PROPVARIANT var;
HRESULT hr = MFCreateSequencerSegmentOffset(ID, NULL, &var);
if (SUCCEEDED(hr))
{
hr = m_pSession->Start(&MF_TIME_FORMAT_SEGMENT_OFFSET, &var);
PropVariantClear(&var);
}
return hr;
}
当应用程序跨段查找时,应用程序会收到多个事件,因为顺序器源结束当前段并准备播放新段。 由于这些事件是异步接收的,因此很难预测事件的确切顺序。 这些事件如下所示:
对媒体会话跳过的新段,顺序器源发送 MENewPresentation 事件。
当顺序器源结束活动段时,它会发送 MEEndOfPresentationSegment 事件。
然后,顺序器源取消预注册拓扑。 这会导致取消的拓扑发生以下事件:
- 带有 MF_TOPOSTATUS_READY 标志的 MESessionTopologyStatus 事件。
- 带有 MF_TOPOSTATUS_STARTED_SOURCE 标志的 MESessionTopologyStatus 事件。
- 具有 MF_EVENT_SOURCE_TOPOLOGY_CANCELED 属性的 MEEndOfPresentationSegment 事件,指示拓扑已由顺序器源取消。
接下来,顺序器源发送新段的事件,包括各种 MESessionTopologyStatus 事件。
如果新段不是列表中的最后一段,则顺序器源会刷新预注册列表,并为新的预注册拓扑引发另一个 MENewPresentation。 有关预注册列表中拓扑的信息,请参阅关于顺序器源。
有关顺序器源发送的事件的更多详细信息,请参阅顺序器源事件主题。
相关主题