对 ASF 流使用相互排除

ASF 内容可以包含多个互斥的流。 这些流不能并发读取,但一次只能读取其中一个流。 例如,文件可以包含一组流,这些流包含以不同比特率编码的相同内容。 所使用的流由流式传输内容的应用程序可用的带宽决定。 ASF 相互排除对象是标头对象的一部分,存储有关互斥流的组的信息。

在媒体基础中,每个 ASF 互斥 对象都存在公开 IMFASFMutualExclusion 接口的互斥对象。 配置文件对象保存对所有互斥对象的引用。

互斥对象将有关互斥流的组的信息存储为记录。 相互排除对象可以有多个记录,这些记录可用于创建复杂方案。 每个记录都包含一个或多个流,这些流不能与另一条记录中的流共存,这些流由互斥对象维护,具体取决于互斥的类型,例如比特率。

复杂互斥的一个常见示例是一个文件,该文件以三种语言中的不同比特率包含相同内容的三个音频流。 一次只能播放九个流中的一个,但它们有两种互斥类型:语言和比特率。

对于此示例,为九个流分配了以下流编号:

1 - 语言 1,比特率 1 2 - 语言 1,比特率 2 3 - 语言 1,比特率 3 4 - 语言 2,比特率 1 5 - 语言 2,比特率 2 6 - 语言 2,比特率 3 7 - 语言 3,比特率 1 8 - 语言 3,比特率 2 9 - 语言 3,比特率 3

可以使用以下四个互斥对象来实现此方案:

  • 第一个互斥对象包括按比特率相互排斥的流 1、2 和 3。 每个流都有自己的记录。
  • 第二个互斥对象包括按比特率相互排斥的流 4、5 和 6。 每个流都有自己的记录。
  • 第三个互斥对象包括 7、8 和 9,按比特率互斥。 每个流都有自己的记录。
  • 第四个互斥对象包含三个记录,第一个包括流 1、2 和 3;第二个包括流 4、5 和 6;和第三个包括流 7、8 和 9。 这些记录按语言互斥。

播放以这种方式创建的文件时,流式处理应用程序首先选择语言,因为它不太可能在演示文稿中更改,然后选择比特率。

互斥对象创建和配置

以下列表总结了配置互斥对象的过程:

  1. 创建互斥对象。
  2. 设置互斥的类型。
  3. 通过添加记录和关联的流来配置互斥对象。
  4. 将互斥对象添加到配置文件。

创建和配置互斥对象

  1. 调用 IMFASFProfile::CreateMutualExclusion 以创建一个空的互斥对象。

  2. 调用 IMFASFMutualExclusion::SetType 以设置互斥流的条件。

    这些流可以按语言、比特率、呈现和自定义条件相互排斥。 类型表示为 GUID。 有关这些常量的列表,请参阅 ASF 互斥类型 GUID

  3. 调用 IMFASFMutualExclusion::AddRecord 将记录添加到互斥对象。

    此方法添加一个空记录,并为其分配一个从零开始的记录索引。

  4. 调用 IMFASFMutualExclusion::AddStreamForRecord 将流编号添加到记录索引指定的记录中。

    每个记录都包含一个或多个流。 记录中的每个流与其他记录中的所有流互斥。 若要获取记录中的流数,请通过指定记录索引调用 IMFASFMutualExclusion::GetStreamsForRecord

    若要从记录中删除流,请调用 IMFASFMutualExclusion::RemoveStreamFromRecord 并指定记录索引和流编号。

  5. 调用 IMFASFProfile::AddMutualExclusion 将配置的互斥对象添加到配置文件。

枚举配置文件中的相互排除对象

如果 IMFASFProfile::AddMutualExclusion 成功,它将为指定的对象分配索引,从零开始。

若要枚举与配置文件关联的互斥对象,请调用 IMFASFProfile::GetMutualExclusionCount ,并通过调用 IMFASFProfile::GetMutualExclusion 循环访问列表。 相互排除索引是连续的,范围为 0 到 1,比 GetMutualExclusionCount 检索的流数少 1。

通过调用 IMFASFProfile::RemoveMutualExclusion,从配置文件中删除互斥对象。 配置文件会重新分配相互排除索引,以便它们按顺序从零开始。 这会覆盖以前存储的索引,这些索引在调用此方法后不再有效。 这会释放关联的互斥流记录。

删除相互排除对象中的记录

若要从相互排除对象中删除记录,请调用 IMFASFMutualExclusion::RemoveRecord。 如果此方法成功,则互斥对象对剩余记录进行索引,使其按顺序从零开始。 应用程序应枚举记录,以确保每个记录的正确索引。 为此,请调用 IMFASFMutualExclusion::GetRecordCount ,并通过调用 IMFASFMutualExclusion::GetStreamsForRecord 循环访问记录。

删除索引最高的记录不会对其他索引产生影响。

修改互斥对象

若要更改配置文件中互斥对象的配置,应用程序必须将现有的互斥对象替换为另一个包含新设置的对象。

更改配置文件中互斥对象的配置

  1. 枚举配置文件中的互斥对象以获取需要更改的对象。

  2. 调用 IMFASFMutualExclusion::Clone 以克隆互斥对象。

  3. 根据需要配置克隆的对象。

  4. 调用 IMFASFProfile::RemoveMutualExclusion 以从配置文件中删除旧的互斥对象。

  5. 调用 IMFASFProfile::AddMutualExclusion 将更新的互斥对象添加到配置文件。

ASF 配置文件