Quality-Based可变比特率编码

与常 量比特率编码 (CBR) 不同,在可变比特率 (VBR) 模式下,编码器努力实现编码媒体的最佳质量。 CBR 和 VBR 之间的主要区别是使用的缓冲区窗口的大小。 与 CBR 编码的流相比,VBR 编码的流通常具有较大的缓冲区窗口。

编码内容的质量取决于压缩内容时丢失的数据量。 许多因素会影响压缩过程中数据丢失;但一般情况下,原始数据越复杂,压缩率越高,压缩过程中越详细。

在基于质量的 VBR 模式下,不会定义编码器必须遵循的比特率或缓冲区窗口。 而是为数字媒体流指定质量级别,而不是比特率。 编码器压缩内容,使所有样本都具有可比的质量;这可确保无论生成的流的缓冲区要求如何,质量在整个播放持续时间内保持一致。

基于质量的 VBR 编码往往创建大型压缩流。 通常,这种类型的编码非常适合本地播放或高带宽网络连接, (或下载和播放) 。 例如,可以编写应用程序,将歌曲从 CD 复制到计算机上的 ASF 文件。 使用基于质量的 VBR 编码可确保复制的所有歌曲的质量都相同。 在这些情况下,一致的质量将提供更好的用户体验。

基于质量的 VBR 编码的缺点是,在编码会话之前,实际上无法知道编码媒体的大小或带宽要求,因为编码器使用单个编码传递。 这可以使基于质量的 VBR 编码文件不适用于内存或带宽受限的情况,例如在便携式媒体播放器上播放内容或通过低带宽网络进行流式传输。

为 Quality-Based VBR 编码配置编码器

编码器配置通过属性值设置。 这些属性在 wmcodecdsp.h 中定义。 在协商输出媒体类型之前,必须在编码器上设置配置属性。 有关如何在编码器上设置属性的信息,请参阅 配置编码器

以下列表显示了必须为此类型的编码设置的属性:

  • 通过将 MFPKEY_VBRENABLED 属性设置为 VARIANT_TRUE 来指定 VBR 编码模式。
  • MFPKEY_PASSESUSED 设置为 1,因为此 VBR 模式使用一个编码传递。
  • 通过设置 MFPKEY_DESIRED_VBRQUALITY 属性,将所需的质量级别 (从 0 设置为 100 ) 。 基于质量的 VBR 不会将内容编码为任何预定义的缓冲区参数。 无论结果的比特率要求如何,都将在整个流中维护此质量级别。
  • 对于视频流,请将编码器输出媒体类型的 MF_MT_AVG_BITRATE 属性中的平均比特率设置为非零值。 编码会话完成后,将更新准确的比特率。

下面的代码示例演示 SetEncodingProperties 的实现。 此函数设置 CBR 和 VBR 的流级编码属性。

//-------------------------------------------------------------------
//  SetEncodingProperties
//  Create a media source from a URL.
//
//  guidMT:  Major type of the stream, audio or video
//  pProps:  A pointer to the property store in which 
//           to set the required encoding properties.
//-------------------------------------------------------------------

HRESULT SetEncodingProperties (const GUID guidMT, IPropertyStore* pProps)
{
    if (!pProps)
    {
        return E_INVALIDARG;
    }

    if (EncodingMode == NONE)
    {
        return MF_E_NOT_INITIALIZED;
    }
   
    HRESULT hr = S_OK;

    PROPVARIANT var;

    switch (EncodingMode)
    {
        case CBR:
            // Set VBR to false.
            hr = InitPropVariantFromBoolean(FALSE, &var);
            if (FAILED(hr))
            {
                goto done;
            }

            hr = pProps->SetValue(MFPKEY_VBRENABLED, var);
            if (FAILED(hr))
            {
                goto done;
            }

            // Set the video buffer window.
            if (guidMT == MFMediaType_Video)
            {
                hr = InitPropVariantFromInt32(VIDEO_WINDOW_MSEC, &var);
                if (FAILED(hr))
                {
                    goto done;
                }

                hr = pProps->SetValue(MFPKEY_VIDEOWINDOW, var);    
                if (FAILED(hr))
                {
                    goto done;
                }
            }
            break;

        case VBR:
            //Set VBR to true.
            hr = InitPropVariantFromBoolean(TRUE, &var);
            if (FAILED(hr))
            {
                goto done;
            }

            hr = pProps->SetValue(MFPKEY_VBRENABLED, var);
            if (FAILED(hr))
            {
                goto done;
            }

            // Number of encoding passes is 1.

            hr = InitPropVariantFromInt32(1, &var);
            if (FAILED(hr))
            {
                goto done;
            }

            hr = pProps->SetValue(MFPKEY_PASSESUSED, var);
            if (FAILED(hr))
            {
                goto done;
            }

            // Set the quality level.

            if (guidMT == MFMediaType_Audio)
            {
                hr = InitPropVariantFromUInt32(98, &var);
                if (FAILED(hr))
                {
                    goto done;
                }

                hr = pProps->SetValue(MFPKEY_DESIRED_VBRQUALITY, var);    
                if (FAILED(hr))
                {
                    goto done;
                }
            }
            else if (guidMT == MFMediaType_Video)
            {
                hr = InitPropVariantFromUInt32(95, &var);
                if (FAILED(hr))
                {
                    goto done;
                }

                hr = pProps->SetValue(MFPKEY_VBRQUALITY, var);    
                if (FAILED(hr))
                {
                    goto done;
                }
            }
            break;

        default:
            hr = E_UNEXPECTED;
            break;
    }    

done:
    PropVariantClear(&var);
    return hr;
}

ASF 编码类型