不受约束的可变比特率编码
在不受约束的可变比特率 (VBR) 编码模式下,内容将编码为尽可能高的质量,同时保持指定的比特率。
无约束 VBR 编码使用两个编码传递。 使用不受约束的 VBR 编码时,可以指定流的比特率,就像使用 常量比特率编码一样。 但是,编码器仅将此值用作流的平均比特率,并对其进行编码,以便在保持平均值的同时尽可能提高质量。 编码器生成的单个样本大小各不相同,没有任何明确的缓冲区限制。 但是,编码会话期间的平均比特率和流的持续时间必须不超过指定的值。 编码流中任意点的实际比特率可能与平均值有很大差异。 不要为不受约束的 VBR 编码设置缓冲区窗口。 编码器会根据编码样本的要求计算所需缓冲区窗口的大小。 这意味着,只要平均比特率小于或等于设置的值,流中各个样本的大小就没有限制。
不受约束的 VBR 编码的优点是压缩流具有最高的质量,同时保持在可预测的平均带宽范围内。 如果需要指定带宽,但围绕指定带宽的波动是可接受的,请使用此选项;例如,对于本地文件或仅下载。
此编码模式的缺点是编码器可以将缓冲区窗口设置为编码后所需的任何值,因此无法控制缓冲区大小。 在大多数情况下,如果你不关心缓冲区的大小或带宽使用情况的一致性,则应使用 基于质量的可变比特率编码
为无约束 VBR 配置编码器
编码器配置是通过属性值设置的。 这些属性在 wmcodecdsp.h 中定义。 在协商输出媒体类型之前,必须在编码器上设置配置属性。 有关如何在编码器上设置属性的信息,请参阅 配置编码器。 根据指定的属性值,可以枚举支持的 VBR 输出类型,并根据平均比特率在编码器 媒体基础转换 (MFT) 中选择所需的类型。
以下列表显示了必须为此类型的编码设置的属性:
- 通过将 MFPKEY_VBRENABLED 属性设置为 VARIANT_TRUE 来指定 VBR 编码模式。
- 将MFPKEY_PASSESUSED设置为 2,因为不受约束的 VBR 模式使用两个编码传递。
- 枚举输出媒体类型时,检查音频流的MF_MT_AUDIO_AVG_BYTES_PER_SECOND属性 () 或视频流的MF_MT_AVG_BITRATE属性 () 可用输出媒体类型。 选择一种输出媒体类型,其平均比特率最接近你希望编码器在编码内容中维护的所需平均比特率。 有关选择输出媒体类型的详细信息,请参阅 编码器上的媒体类型协商。
若要获取编码器设置的缓冲区窗口值,请在编码会话后调用在 wmcodecifaces.h 和 wmcodecdspuuid.lib 中定义的 IWMCodecLeakyBucket::GetBufferSizeBits。 若要为流添加不受约束的 VBR 支持,必须在配置 ASF 配置文件时在 流 配置对象上) (MF_ASFSTREAMCONFIG_LEAKYBUCKET1属性中设置此值。
下面修改了示例类 CEncoder 的 SetEncodingType 方法,以设置不受约束的 VBR 模式。 有关此类的信息,请参阅 编码器示例代码。 有关此示例中使用的帮助程序宏的信息,请参阅使用媒体基础代码示例。
//////////////////////////////////////////////////////////////////////////
// Name: SetEncodingType
// Description: Sets the encoding type to unconstrained VBR
//
/////////////////////////////////////////////////////////////////////////
HRESULT CEncoder::SetEncodingType(EncodeMode mode)
{
if (!m_pMFT)
{
return MF_E_NOT_INITIALIZED;
}
HRESULT hr = S_OK;
IPropertyStore* pProp = NULL;
PROPVARIANT var;
PropVariantInit(&var);
//Query the encoder for its property store
CHECK_HR(hr = m_pMFT->QueryInterface(__uuidof(IPropertyStore), (void**)&pProp));
if (mode == EncodeMode_VBR_Unconstrained)
{
//Set the VBR property to TRUE, which indicates VBR encoding
var.vt = VT_BOOL;
var.boolVal = TRUE;
CHECK_HR(hr = pProp->SetValue(MFPKEY_VBRENABLED, var));
PropVariantClear(&var);
//Set number of passes
var.vt = VT_I4;
var.lVal =2;
CHECK_HR(hr = pProp->SetValue(MFPKEY_PASSESUSED, var));
PropVariantClear(&var);
}
done:
PropVariantClear(&var);
SAFE_RELEASE (pProp);
return hr;
}
相关主题