配置配置文件和其他 ASF 文件属性

[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayerIMFMediaEngine媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

以下各项介绍如何执行与创建 ASF 文件相关的各种任务。 本主题中提到的一些接口记录在 Windows Media 格式 SDK 文档中。

创建配置文件

Windows Media Format SDK 中详细介绍了 ASF 配置文件;实质上,它们描述 Windows Media Format 文件的属性,例如比特率、流的数量和类型以及压缩质量。 筛选器使用配置文件来确定要写入的 Windows Media Format 文件的类型、它必须设置多少个输入引脚以及它们可以接受的媒体类型。

若要创建自定义配置文件,请直接使用 Windows 媒体格式 SDK 通过 WMCreateProfileManager 函数创建配置文件管理器对象。 接下来,创建配置文件,并使用 IConfigASFWriter::ConfigureFilterUsingProfile 方法将其传递给 WM ASF 编写器。 这是使用使用 Windows Media 音频和视频 9 系列编解码器的配置文件配置筛选器的唯一方法。 可以使用 IConfigASFWriter::ConfigureFilterUsingProfileGuid 方法添加这些编解码器早期版本的系统配置文件。

只要新配置文件不需要任何其他输入引脚,就可以在连接筛选器的输入引脚时重置配置文件。 例如,如果将配置文件从单输入仅音频配置文件更改为双输入音频和视频配置文件,则只会重新连接音频引脚,并且不会为视频流创建新 PIN。

添加元数据

若要将元数据添加到文件,请查询 IWMHeaderInfo 接口的 WM ASF 编写器筛选器。 为筛选器提供配置文件后,请使用 IWMHeaderInfo 接口方法写入元数据。

为文件编制索引

默认情况下,WM ASF 编写器创建临时索引文件。 若要创建帧索引文件,请使用 IConfigAsfWriter::SetIndexMode 方法禁用所有索引,然后创建该文件。 完成后,直接使用 Windows Media 格式 SDK 为文件创建基于帧的索引。

Two-Pass编码

只有版本 8 及更高版本的 Windows Media 编解码器才支持双重编码。 调用 IConfigAsfWriter2::SetParam 并在 dwParam 参数中指定AM_CONFIGASFWRITER_PARAM_MULTIPASS,在 dwParam1 参数中指定 TRUE ,将 WM ASF 编写器置于预处理模式。

然后运行筛选器图。 当完成所有预处理阶段 (通常只执行一个预处理过程) 时,应用程序将从筛选器接收 EC_PREPROCESS_COMPLETE 事件。 收到此事件后,使用 IMediaSeeking::SetPositions 将流指针重置回开头,然后再次运行筛选器图。 在最后一次传递 (通常是第二次传递) 之后,应用程序将收到 一个EC_COMPLETE 事件,表示编码过程已完成。 如果在收到 EC_PREPROCESS_COMPLETE 事件之前取消了预处理阶段,请在尝试另一个预处理运行之前调用 IConfigAsfWriter2::ResetMultiPassState 重置筛选器。

仅当希望将筛选器完全退出预处理模式时,才需要将 AM_CONFIGASFWRITER_PARAM_MULTIPASS 参数设置为 FALSE

重要

应用程序负责根据将用于编码的配置文件启用预处理模式。 某些配置文件需要双重编码;如果尝试使用此类配置文件对文件进行编码,但未将AM_CONFIGASFWRITER_PARAM_MULTIPASS设置为 TRUE,则会导致 EC_USERABORT 错误。 有关详细信息,请参阅 Windows Media 格式 SDK 文档。

 

在运行时获取和设置缓冲区属性

在某些情况下,例如,如果要在写入文件时强制关键帧插入,应用程序可能需要在运行时获取或设置有关 Windows Media 缓冲区的信息。 WM ASF 读取器和WM ASF 编写器筛选器都支持回调机制,使应用程序能够在文件读取或写入期间访问每个媒体缓冲区上的 INSSBuffer3 接口。 应用程序可以使用此接口将特定示例指定为关键帧、设置 SMPTE 时间代码、指定交错设置或将任何类型的专用数据添加到流中。

使用 IAMWMBufferPass 接口从处理视频流的引脚注册回调。 引脚将为每个缓冲区调用 IAMWMBufferPassCallback::Notify 方法。

非平方像素

WM ASF 编写器连接到输出像素纵横比信息的上游筛选器,例如 DV 解码器。 WM ASF 编写器会将此信息作为文件中的每个示例的数据单元扩展写入。

当 WM ASF 读取器在示例的文件标头或数据单元扩展中遇到像素纵横比信息时,它将在其输出引脚上提供 VIDEOINFOHEADER2 格式作为第一选择。 结构的 dwPictAspectRatioXdwPictAspectRatioY 成员(描述视频矩形的纵横比)将正确调整,以考虑像素纵横比。

维护隔行扫描格式

如果从电视或 DV 相机捕获交错视频,如果希望编码文件在电视或其他交错显示设备上播放,则可能需要将原始视频保留为独立字段。 (计算机监视器是渐进式扫描设备。) 如果取消隔行扫描视频,然后将其重新交错以在电视上播放,则会产生一些数据丢失。 在 ASF 文件中,交错信息存储为数据单元扩展,应用程序使用前面所述的 IAMWMBufferPassCallback 方法应用于每个示例。 若要对保留原始交错设置的文件进行编码,请执行以下步骤:

  1. 实现支持 IAMWMBufferPassCallback 的 类,并编写一个 Notify 函数来设置每个示例的交错标志。 在处理每个示例之前,WM ASF 编写器将调用此函数。

    // Set to WM_CT_TOP_FIELD_FIRST if that is your format.
    BYTE flag = WM_CT_INTERLACED | WM_CT_BOTTOM_FIELD_FIRST;
    HRESULT hr = S_OK;
    
    hr = pNSSBuffer3->SetProperty(
        WM_SampleExtensionGUID_ContentType, 
        (void*) &flag, 
        WM_SampleExtension_ContentType_Size
        );         
    
  2. 在将配置文件传递到筛选器之前,在配置文件上设置数据单元扩展。

    hr = pWMStreamConfig2->AddDataUnitExtension(
        WM_SampleExtensionGUID_ContentType, 
        WM_SampleExtension_ContentType_Size, 
        NULL, 
        0 
        );
    
  3. 使用配置文件配置筛选器后,从 WM ASF 编写器获取 IWMWriterAdvanced2 接口并调用 SetInputSettings 方法。

    ``

    ``

    // Must do this first.
    hr = pConfigAsfWriter2->ConfigureFilterUsingProfile(pProfile);
    
    CComPtr<IServiceProvider> pProvider;
    CComPtr<IWMWriterAdvanced2> pWMWA2;
    
    hr = pConfigAsfWriter2->QueryInterface( __uuidof(IServiceProvider),
                                             (void**)&pProvider);
    if (SUCCEEDED(hr))
    {
        hr = pProvider->QueryService(IID_IWMWriterAdvanced2,
            IID_IWMWriterAdvanced2,
            (void**)&pWMWA2);
    }
    
    BOOL pValue = TRUE;
    
    // Set the first parameter to your actual input number.
    hr = pWMWA2->SetInputSetting(0, g_wszInterlacedCoding,
        WMT_TYPE_BOOL, (BYTE*) &pValue, sizeof(WMT_TYPE_BOOL));
    
    

在 DirectShow 中创建 ASF 文件