创建多路复用器对象

ASF 多路复用器是与 ASF 数据对象 一起使用的 WMContainer 层对象,使应用程序能够为媒体流生成 ASF 数据包。

多路复用器对象公开 IMFASFMultiplexer 接口。 若要创建多路复用器,请调用 MFCreateASFMultiplexer。 此函数返回指向空对象的指针。 如果应用程序正在编写新的 ASF 文件,则应用程序必须使用 ContentInfo 对象初始化多路复用器。 为此,请调用 IMFASFMultiplexer::Initialize。 指定的 ContentInfo 对象表示新文件的 ASF 标头对象。 有关为新文件创建和初始化 ContentInfo 对象的信息,请参阅 初始化新 ASF 文件的 ContentInfo 对象

Initialize 方法分析 ContentInfo 对象以收集流配置信息,例如流数、数据包大小、预滚动。 (可选)多路复用器可能还需要泄漏的存储桶参数和有效负载扩展单元。 若要生成符合 ASF 标头对象中定义的要求的数据包,需要此信息。 Initialize 方法根据流的媒体类型和配置设置配置多路复用器。 例如,如果将流配置为具有有效负载扩展 (请参阅 创建和配置 ASF 流) ,然后将多路复用器配置为将这些值添加到生成的数据包。

Initialize 方法还会获取初始数据对象的句柄,该对象是在创建 ContentInfo 对象期间创建的,用于写入。 在数据包生成期间,多路复用器会将数据包添加到数据对象,并相应地对其进行更新。 多路复用器生成所有数据包后,它会更新提供的 ContentInfo 对象,以便更新某些值,例如数据包数。

下面的代码示例演示如何创建多路复用器并使用 ContentInfo 对象对其进行初始化。

//-------------------------------------------------------------------
// CreateOutputGenerators
//
// Creates the ASF mux and the ASF Content Info object for the 
// output file.
//-------------------------------------------------------------------

HRESULT CreateOutputGenerators(
    IMFASFProfile *pProfile, 
    IMFASFContentInfo **ppContentInfo, 
    IMFASFMultiplexer **ppMux
    )
{
    IMFASFContentInfo *pContentInfo = NULL;
    IMFASFMultiplexer *pMux = NULL;

    // Use the ASF profile to create the ContentInfo object.
    HRESULT hr = MFCreateASFContentInfo(&pContentInfo);

    if (SUCCEEDED(hr))
    {
        hr = pContentInfo->SetProfile(pProfile);
    }

    // Create the ASF Multiplexer object.
    if (SUCCEEDED(hr))
    {
        hr = MFCreateASFMultiplexer(&pMux);
    }
    
    // Initialize it using the new ContentInfo object.
    if (SUCCEEDED(hr))
    {
        hr = pMux->Initialize(pContentInfo);
    }

    // Return the pointers to the caller.
    if (SUCCEEDED(hr))
    {
        *ppContentInfo = pContentInfo;
        (*ppContentInfo)->AddRef();

        *ppMux = pMux;
        (*ppMux)->AddRef();
    }

    SafeRelease(&pContentInfo);
    SafeRelease(&pMux);

    return hr;
}

若要查看完整应用程序中使用的此函数,请参阅 教程:将 ASF 流从一个文件复制到另一个文件

多路复用器初始化和泄漏存储桶设置

IMFASFMultiplexer::Initialize 方法配置多路复用器以确定泄漏的存储桶数据流。 若要配置这些参数,请确保在指定的 ContentInfo 对象上设置以下属性值。 有关设置这些属性的信息,请参阅 在 ContentInfo 对象中设置属性

  • MFPKEY_ASFMEDIASINK_AUTOADJUST_BITRATE 属性:这指示多路复用器是否需要自动调整比特率,以维护泄漏存储桶中的数据流。 应用程序可以通过调用 IMFASFMultiplexer::SetFlags 并传递 MFASF_MULTIPLEXER_AUTOADJUST_BITRATE 标志来更改此设置。

  • MFPKEY_ASFMEDIASINK_BASE_SENDTIME 属性:发送时间指示何时释放泄漏存储桶中的有效负载。 发送时间必须等于或早于演示时间,因为有效负载必须在演示时间之前有时间到达目标。

    此属性值为第一次发送时间。 多路复用器使用此值计算后续发送时间,以确保数据稳定地流经存储桶。 如果在多路复用器上设置了 MFASF_MULTIPLEXER_AUTOADJUST_BITRATE 标志,多路复用器将调整比特率,以便在缓冲区窗口接近满时发送有效负载。 如果未设置标志,则由于带宽溢出,多路复用器无法生成数据包。

多路复用器从与 Initialize 方法中指定的 ContentInfo 对象关联的 ASF 配置文件中获取流配置信息。 流配置信息包括泄漏的存储桶参数。 多路复用器需要此值来生成数据包。

若要指定泄漏存储桶参数,请在表示配置文件中流的流配置对象的 MF_ASFSTREAMCONFIG_LEAKYBUCKET1 属性中设置值。 若要使用编码器使用的缓冲区窗口值,请调用 IWMCodecLeakyBucket::GetBufferSizeBits。 只有在设置编码器的输出媒体类型后,才会知道实际的缓冲区窗口值。 有关设置输出媒体类型的信息,请参阅 编码器上的媒体类型协商

注意

编码器使用的泄漏存储桶值在用于创建多路复用器时由 ASF 配置文件提供的 ContentInfo 对象中可能不同。

 

Initialize 方法更新 ContentInfo 对象,以便正确的值反映在最终的 ASF 标头对象中。

ASF 多路复用器

生成新的 ASF 数据包