使用第三方编解码器创建 ASF 文件

[与此页面关联的功能 Windows Media Format 11 SDK 是一项旧功能。 它已被源读取器和接收器编写器取代。 源读取器和接收器编写器已针对Windows 10和Windows 11进行了优化。 如果可能,Microsoft 强烈建议新代码使用源读取器和接收器编写器,而不是 Windows Media 格式 11 SDK。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

可以使用 Windows Media Format SDK 创建包含使用所选任何编解码器编码的数字媒体的 ASF 文件。 使用此 SDK 附带的编解码器以外的编解码器时,必须执行以下步骤。

  1. 使用所需的编解码器对内容进行编码。
  2. 查找或创建 GUID 值,以标识使用步骤 1 中使用的编解码器编码的内容。
  3. 创建新的配置文件,或修改现有配置文件以用于编码的内容。
    • 为具有相应主要类型的编码内容创建流。 有关主要媒体类型的详细信息,请参阅 媒体类型。 使用步骤 2 中标识的 GUID 作为媒体子类型。
    • 将流的比特率和缓冲区窗口设置为不会导致缓冲区溢出的值。 应该能够在编码时从编解码器获取这些值。 SDK 运行时组件检查比特率/缓冲区窗口值,并在必要时删除样本,以使给定数据适合这些值。 如果设置的值不正确,文件将无法正确流式传输,从而导致播放效果不佳。
    • 对于视频流,必须将 WMVIDEOINFOHEADER 结构中包含的 BITMAPINFOHEADER 结构的 biCompression 成员设置为内容的相应 FOURCC 值。 此值必须等于子类型 GUID 的前四个字节。 例如,如果 biCompression 是 MAKEFOURCC ('T'、'E'、'S'、'T') =0x54455354,则子类型 GUID 将如下所示开始:54455354-XXXX-XXXX-XXXX-XXXXXXXXXXXX。
  4. 创建编写器对象并加载在上一步中创建的配置文件。 有关写入文件的详细信息,请参阅 编写 ASF 文件
  5. 循环访问文件的输入,并像平常一样为每个输入属性分配输入属性。 有关输入的详细信息,请参阅 使用输入。 对于使用第三方编解码器编码的流,在调用 IWMWriter::BeginWriting 之前,将 IWMInputMediaProps 接口指针设置为 NULL
  6. 使用在上一步中创建的新配置文件写入文件。 使用 IWMWriterAdvanced::WriteStreamSample 而不是 IWMWriter::WriteSample 传递压缩样本。 对于视频,必须通过将WM_SF_CLEANPOINT作为 dwFlags 参数传递来指定哪些样本是关键帧。

若要处理和解压缩使用第三方编解码器编码的流,必须读取压缩的流示例。 读取应用程序还必须处理流的示例解压缩。

将 MPEG-2 流放入 ASF

注意

本主题适用于使用 Windows Media Format SDK 将 MPEG-2 (或其他使用 B 帧) 的压缩格式放入 ASF 文件容器的应用程序。

 

编写器对象要求所有输入样本都具有时间戳,并且假定每个输入样本的呈现时间晚于其前面的时间。 尽管几乎所有未压缩的视频,甚至某些压缩的视频流都满足这些条件,但 MPEG-2 流则不满足这些条件。 在 MPEG-2 中,并非所有样本都带有时间戳,当存在 B 帧时,样本解码顺序与呈现顺序不同。 当编写器对象遇到无序样本时,它会将它们重新排列为“正确”顺序。 因此,若要在 ASF 容器中以本机 (未解码) 存储 MPEG-2 流,必须执行以下步骤:

写入文件时:

  1. 将固定大小的数据单位扩展 (DUE) 添加到每个输入样本,该示例将保存包含样本的实际 MPEG 时间戳开始时间和停止时间值的 结构。 如果示例没有时间戳,则对这些值使用 -1。
  2. 为编写器对象提供始终递增的“虚拟”输入时间戳,以便其按接收时完全相同的顺序将示例写入文件。 虚拟时间戳应大致对应于实际呈现时间(随时间推移的平均值)。 虚拟时间戳将形成查找时间线,因此,如果它们相对于实时时间戳存在分歧,则对文件执行查找操作将产生意外结果。 但是,采样时间之间的有限抖动量不会严重影响搜寻操作。

读取文件时:

  • 对于从文件读取的每个示例,检查 DUE。 如果它包含的开始时间大于或等于零,请将该值复制到输出示例的时间戳中,然后再将其传递到解码器。 将输出样本上的所有其他时间戳设置为 NULL。 在 DirectShow 中,可通过调用 IMediaSample::SetTime (NULLNULL) 来完成此操作。

缓冲内容

IWMWriter 接口

IWMWriterAdvanced 接口

使用异步读取器传递压缩示例

使用同步读取器检索流样本

WMVIDEOINFOHEADER

使用配置文件

编写 ASF 文件