常量比特率编码
在常量比特率(CBR)编码中,编码器知道编码会话开始前输出媒体样本和缓冲区窗口(泄漏存储桶参数)的比特率。 编码器在整个文件的持续时间内使用相同的位数对样本的每一秒进行编码,以实现流的目标比特率。 这会限制流样本大小的变化。 此外,在编码会话期间,比特率不完全位于指定值,而是与目标比特率保持接近。
如果想要了解文件的比特率或近似持续时间,而不分析整个文件时,CBR 编码非常有用。 在实时传送视频流方案中,需要以可预测的比特率和一致的带宽使用率对媒体内容进行流式传输。
CBR 编码的缺点是编码内容的质量不会保持不变。 由于某些内容更难以压缩,因此 CBR 流的部分质量比其他内容低。 例如,典型的电影具有一些相当静态的场景和一些充满动作的场景。 如果使用 CBR 对电影进行编码,则静态场景(因此易于高效编码)的质量将高于作场景,该场景需要更高的样本大小来保持相同的质量。
一般情况下,CBR 文件质量的变化在较低的比特率下更为明显。 比特率较高,CBR 编码文件的质量仍会有所不同,但质量问题对用户不太明显。 使用 CBR 编码时,应将带宽设置为传送方案允许的带宽。
CBR 配置设置
必须在编码会话之前指定编码类型和各种流特定设置来配置编码器。
为 CBR 编码配置编码器
指定 CBR 编码模式。
默认情况下,编码器配置为使用 CBR 编码。 编码器配置是通过属性值设置的。 这些属性在 wmcodecdsp.h 中定义。 可以通过将 MFPKEY_VBRENABLED 属性设置为VARIANT_FALSE来显式指定此模式。 有关如何在编码器上设置属性的信息,请参阅 配置编码器。
选择编码比特率。
对于 CBR 编码,必须在编码会话开始之前知道要对流进行编码的比特率。 在配置编码器期间,必须设置比特率。 为此,在执行媒体类型协商时,请检查可用输出媒体类型的 MF_MT_AUDIO_AVG_BYTES_PER_SECOND 属性(对于音频流)或 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;
}
泄漏存储桶设置
对于 CBR 编码,流的平均值和最大泄漏存储桶值是相同的。 有关这些参数的详细信息,请参阅 泄漏的存储桶缓冲区模型。
若要 CBR 编码音频流,需要在编码器上协商输出媒体类型后设置泄漏的存储桶值。 编码器根据输出媒体类型上设置的平均比特率在内部计算缓冲区窗口。
若要设置泄漏存储桶值,请创建 DWORD 数组,可以在媒体接收器的属性存储中的 MFPKEY_ASFSTREAMSINK_CORRECTED_LEAKYBUCKET 属性中设置以下值。 有关详细信息,请参阅 在文件接收器中设置属性。
- 平均比特率:从媒体类型协商期间选择的输出媒体类型获取平均比特率。 使用 MF_MT_AUDIO_AVG_BYTES_PER_SECOND 属性。
- 缓冲区窗口:查询 IWMCodecLeakyBucket 接口的编码器,然后调用 IWMCodecLeakyBucket::GetBufferSizeBits(wmcodecifaces.h, wmcodecdspuuid.lib)。
- 初始缓冲区大小:设置为 0。
相关主题