Quality-Based可变比特率编码

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

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

在基于质量的 VBR 模式下,不定义编码器必须遵循的比特率或缓冲区窗口。 而是指定数字媒体流的质量级别,而不是比特率。 编码器会压缩内容,以便所有样本的质量相当;这可确保在播放期间质量一致,而不考虑生成的流的缓冲区要求。

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

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

为 VBR 编码Quality-Based编码器

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

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

  • MFPKEY _ VBRENABLED 属性设置为 VARIANT TRUE,指定 VBR _ 编码模式。
  • MFPKEY _ PASSSUSED 设置为 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 编码类型