[关闭]
@ltlovezh 2021-09-02T09:07:05.000000Z 字数 3007 阅读 496

码率控制

音视频


码率控制就是给定输入视频,在给定的时间内输出满足码率要求的一个编码决策过程。

bitrate mode

CBR(Constant bitrate mode)

CBR(Constant BitRate)是以恒定比特率方式进行编码,由于码率恒定,有Motion发生时,图像质量变差(码率不够),当场景静止时,图像质量又变好(码率浪费),因此图像质量不稳定,这种算法优先考虑码率(带宽)。
ffmpeg设置方式:

  1. // 平均码率
  2. AVCodecContext->bit_rate = bitrate;
  3. // 最小码率
  4. AVCodecContext->rc_min_rate = bitrate;
  5. // 最大码率
  6. AVCodecContext->rc_max_rate = bitrate;
  7. // we must set rc_buffer_size once we have set rc_max_rate
  8. AVCodecContext->rc_buffer_size = bitrate;

VBR(Variable bitrate mode)

VBR(Variable BitRate)可变码率,即码率可以随着图像复杂程度的不同而变化。码率控制算法根据图像内容确定使用的码率,图像内容比较简单则分配较少码率,图像内容复杂则分配较多码率,这样既保证质量,又兼顾带宽,这种算法优先考虑图像质量。

ABR(Average Bitrate)

平均码率,属于VBR的一种,就是设定编码文件的平均码率,编码过程中根据编码图像内容分配不同的码率,最终编码结束时达到设定的平均码率。

ffmpeg设置方式:

  1. // 平均码率
  2. AVCodecContext->bit_rate = bitrate;
  3. // In ABR mode, we set rc_min_rate/rc_max_rate/rc_buffer_size to 0
  4. AVCodecContext->rc_min_rate = 0;
  5. AVCodecContext->rc_max_rate = 0;
  6. AVCodecContext->rc_buffer_size = 0;

CQP(Constant Quantization Parameter)

恒定量化参数,所有编码图像区域,即编码帧、编码Slice,都使用相同QP,即追求量化失真的恒定,瞬时码率会随场景复杂度而波动。这种模式基本被CRF取代,只有用–qp 0来进行无损编码还有价值。

针对FFmpeg x264编码器,可以以qp为Key,设置qp值,范围为0~51,值越小,量化损失越小,0表示无损。

  1. AVDictionary *opt = nullptr;
  2. const char *qp = "2";
  3. av_dict_set(&opt, "qp", qp, 0);
  4. // 打开编码器,把opt参数设置给编码器
  5. avcodec_open2(AVCodecContext, AVCodec, &opt);

CRF(Constant rate factor)

恒定质量因子,追求主观感知到的质量恒定,瞬时码率也会随场景复杂度波动。 对于快速运动或细节丰富的场景会适当增大量化失真(因为人眼不易注意到),反之对于静止或平坦区域则减少量化失真。

CRF取值范围为0~51,值越低,质量越好,文件越大。
x264的一般取值为18-28,默认值是23,x265默认值是28。
CRF

为了让主观质量差不多,CRF编码过程中会使用不同的QP值,对于运动比较大的场景,会把QP设得更高一些,对于静止帧,会降低QP,这会导致码率分配随时间变化不同。

比起运动物体,人眼对静止物体会观察到更多细节。基于这一想法,编码时,对运动物体给更高压缩率(增大QP),而对静止物体保留更多细节(减少QP)。

针对FFmpeg x264编码器,可以以crf为Key,设置crf值。

  1. AVDictionary *opt = nullptr;
  2. const char *crf = "23";
  3. // 如果采用码率策略,且maxBitrate值合法,则设置最大max_rate;否则采用zerolatency模式
  4. if(maxBitrate > 0){
  5. // max_rate可能有20%的码率波动,所以将max_rate设置为0.8倍
  6. AVCodecContext->rc_max_rate = 0.8 * maxBitrate;
  7. AVCodecContext->rc_buffer_size = 0.8 * maxBitrate * 2;
  8. // 去掉zerolantacy,码率和psnr均会上升,通过增加crf来平衡
  9. av_dict_set(&opt, "crf", crf + 3, 0);
  10. } else {
  11. // zerolatency表示零延迟
  12. av_dict_set(&opt, "tune", "zerolatency", 0);
  13. av_dict_set(&opt, "crf", crf, 0);
  14. }
  15. // 打开编码器,把opt参数设置给编码器
  16. avcodec_open2(AVCodecContext, AVCodec, &opt);

整体看,CBR是独立一类,编码过程中,码率不变,其他都属于VBR,编码过程中,码率跟随场景而变化。

X264编码参数

Profile

Profile是对视频压缩特性的描述,主要有Baseline、Main Profile(MP)、High Profile(HP)等,从左到右编码效率不断提高,清晰度也有所提升。

Level

Level是对视频本身特性的描述(码率、分辨率、fps),Level越高,视频的码率、分辨率、fps越高。

在给定Profile下,level通常与编解码器的处理能力和内存容量相对应。每一个档次设置不同的参数(码率、分辨率、fps),得到对应编解码器性能的不同level,level分级如下所示:
Level

preset

表示编码质量(压缩效率)和编码速度之间的平衡,取值如下:

  1. ultrafast
  2. superfast
  3. veryfast
  4. faster
  5. fast
  6. medium
  7. slow
  8. slower
  9. veryslow
  10. placebo

从上到下,编码速度越来越慢,编码质量越来越好,压缩效率越来越高,默认值是medium

tune

tune是x264中重要性仅次于preset的选项,它是视觉优化的参数,tune可以理解为视频偏好或者视频类型,有如下取值:

合成发布场景

硬编码

VBR + 指定码率 + 指定Profile

软编码

Preset、CRF和MaxRate组合,不同国家使用不同策略。
Preset越小,合成速度越快,但是压缩效率越低。(合成发布场景下,Preset应该越小越好)
CRF越小,画质越好,码率越大。
AVCodecContext->rc_max_rateAVCodecContext->rc_buffer_size一起限制最大码率。

参考文档

  1. CRF和QP的区别
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注