@ltlovezh
2023-03-05T11:41:26.000000Z
字数 3007
阅读 1791
音视频
码率控制就是给定输入视频,在给定的时间内输出满足码率要求的一个编码决策过程。
CBR(Constant BitRate)是以恒定比特率方式进行编码,由于码率恒定,有Motion发生时,图像质量变差(码率不够),当场景静止时,图像质量又变好(码率浪费),因此图像质量不稳定,这种算法优先考虑码率(带宽)。
ffmpeg设置方式:
// 平均码率
AVCodecContext->bit_rate = bitrate;
// 最小码率
AVCodecContext->rc_min_rate = bitrate;
// 最大码率
AVCodecContext->rc_max_rate = bitrate;
// we must set rc_buffer_size once we have set rc_max_rate
AVCodecContext->rc_buffer_size = bitrate;
VBR(Variable BitRate)可变码率,即码率可以随着图像复杂程度的不同而变化。码率控制算法根据图像内容确定使用的码率,图像内容比较简单则分配较少码率,图像内容复杂则分配较多码率,这样既保证质量,又兼顾带宽,这种算法优先考虑图像质量。
平均码率,属于VBR的一种,就是设定编码文件的平均码率,编码过程中根据编码图像内容分配不同的码率,最终编码结束时达到设定的平均码率。
ffmpeg设置方式:
// 平均码率
AVCodecContext->bit_rate = bitrate;
// In ABR mode, we set rc_min_rate/rc_max_rate/rc_buffer_size to 0
AVCodecContext->rc_min_rate = 0;
AVCodecContext->rc_max_rate = 0;
AVCodecContext->rc_buffer_size = 0;
恒定量化参数,所有编码图像区域,即编码帧、编码Slice,都使用相同QP,即追求量化失真的恒定,瞬时码率会随场景复杂度而波动。这种模式基本被CRF取代,只有用–qp 0
来进行无损编码还有价值。
针对FFmpeg x264编码器,可以以qp
为Key,设置qp值,范围为0~51,值越小,量化损失越小,0表示无损。
AVDictionary *opt = nullptr;
const char *qp = "2";
av_dict_set(&opt, "qp", qp, 0);
// 打开编码器,把opt参数设置给编码器
avcodec_open2(AVCodecContext, AVCodec, &opt);
恒定质量因子,追求主观感知到的质量恒定,瞬时码率也会随场景复杂度波动。 对于快速运动或细节丰富的场景会适当增大量化失真(因为人眼不易注意到),反之对于静止或平坦区域则减少量化失真。
CRF取值范围为0~51,值越低,质量越好,文件越大。
x264的一般取值为18-28,默认值是23,x265默认值是28。
为了让主观质量差不多,CRF编码过程中会使用不同的QP值,对于运动比较大的场景,会把QP设得更高一些,对于静止帧,会降低QP,这会导致码率分配随时间变化不同。
比起运动物体,人眼对静止物体会观察到更多细节。基于这一想法,编码时,对运动物体给更高压缩率(增大QP),而对静止物体保留更多细节(减少QP)。
针对FFmpeg x264编码器,可以以crf
为Key,设置crf值。
AVDictionary *opt = nullptr;
const char *crf = "23";
// 如果采用码率策略,且maxBitrate值合法,则设置最大max_rate;否则采用zerolatency模式
if(maxBitrate > 0){
// max_rate可能有20%的码率波动,所以将max_rate设置为0.8倍
AVCodecContext->rc_max_rate = 0.8 * maxBitrate;
AVCodecContext->rc_buffer_size = 0.8 * maxBitrate * 2;
// 去掉zerolantacy,码率和psnr均会上升,通过增加crf来平衡
av_dict_set(&opt, "crf", crf + 3, 0);
} else {
// zerolatency表示零延迟
av_dict_set(&opt, "tune", "zerolatency", 0);
av_dict_set(&opt, "crf", crf, 0);
}
// 打开编码器,把opt参数设置给编码器
avcodec_open2(AVCodecContext, AVCodec, &opt);
整体看,CBR是独立一类,编码过程中,码率不变,其他都属于VBR,编码过程中,码率跟随场景而变化。
Profile是对视频压缩特性的描述,主要有Baseline、Main Profile(MP)、High Profile(HP)等,从左到右编码效率不断提高,清晰度也有所提升。
Level是对视频本身特性的描述(码率、分辨率、fps),Level越高,视频的码率、分辨率、fps越高。
在给定Profile下,level通常与编解码器的处理能力和内存容量相对应。每一个档次设置不同的参数(码率、分辨率、fps),得到对应编解码器性能的不同level,level分级如下所示:
表示编码质量(压缩效率)和编码速度之间的平衡,取值如下:
从上到下,编码速度越来越慢,编码质量越来越好,压缩效率越来越高,默认值是medium
。
tune是x264中重要性仅次于preset的选项,它是视觉优化的参数,tune可以理解为视频偏好或者视频类型,有如下取值:
VBR + 指定码率 + 指定Profile
Preset、CRF和MaxRate组合,不同国家使用不同策略。
Preset越小,合成速度越快,但是压缩效率越低。(合成发布场景下,Preset应该越小越好)
CRF越小,画质越好,码率越大。
AVCodecContext->rc_max_rate
和AVCodecContext->rc_buffer_size
一起限制最大码率。