ffmpeg 码率控制(总结篇)

本文仅探讨ffmpeg API编码的方式进行码率控制,文中测试数据使用的是网络传输场景,非本地测试,可能收到网络的影响。如有不足之处,请及时指正。

CQP

CQP:Constant Quantization Parameter - 固定质量参数

每一帧图像在压缩时,采用相同的量化参数QP(量化参数QP定义了从一个像素宏块中丢掉多少信息),单位像素丢掉的数据比例是一致的,然后再结合运动矢量,最终形成压缩后的帧,不决定相对码率的大小。

运行比较剧烈的帧相对于运动不剧烈的帧,单位时间内要表现的内容该多还是多,单位时间的码率该高还是高。

代码实现:

// CQP
av_opt_set(pOutVideoCodecCtx->priv_data, "qp", "23", AV_OPT_SEARCH_CHILDREN);

测试表现:
ffmpeg 码率控制(总结篇)_第1张图片

CRF

CRF:Constant Rate Factor - 限制码率因子

CRF是264和265中默认的质量/码率控制设置。这个值可以在0到51之间,值越低,质量越好,文件大小越大。

  1. 量化比例的范围为0~51,其中0为无损模式,23为缺省值,51可能是最差的。该数字越小,图像质量越好。从主观上讲,18~28是一个合理的范围。18往往被认为从视觉上看是无损的,它的输出视频质量和输入视频一模一样或者说相差无几。但从技术的角度来讲,它依然是有损压缩。

  2. 若Crf值加6,输出码率大概减少一半;若Crf值减6,输出码率翻倍。通常是在保证可接受视频质量的前提下选择一个最大的Crf值,如果输出视频质量很好,那就尝试一个更大的值,如果看起来很糟,那就尝试一个小一点值。

CRF比CQP要一些,CRF会用将每一帧的压缩不同的大小,为了让主观的质量感受差不多,会用不同的QP。他是通过把运动也考虑进来做到这一点的。在编码中,如果Qp=18,则每一帧都是QP=18,当然根据帧的类型不同会有一些微小的波动,忽略之。设置CRF=18的时候,对于运动比较大的场景,会把QP设得更高一些,对于运动比较比较不剧烈的帧,会降低QP。这会导致比特率的分配随时间变化不同。

代码实现:

// CRF
av_opt_set(pOutVideoCodecCtx->priv_data, "crf", "23", AV_OPT_SEARCH_CHILDREN);

测试表现:
ffmpeg 码率控制(总结篇)_第2张图片

CBR

CBR:Constant BitRate - 固定比特率

是恒定(固定)比特率,指文件每秒钟的码率是固定不变的。

CBR VBR ABR的区别
可参考:https://blog.csdn.net/Martin_chen2/article/details/105714088

代码实现:

// CBR
int bitRate = 800000;
pOutVideoCodecCtx->bit_rate = bitRate;
pOutVideoCodecCtx->rc_min_rate = bitRate;
pOutVideoCodecCtx->rc_max_rate = bitRate;
pOutVideoCodecCtx->bit_rate_tolerance = bitRate;
pOutVideoCodecCtx->rc_buffer_size = bitRate;
pOutVideoCodecCtx->rc_initial_buffer_occupancy = pOutVideoCodecCtx->rc_buffer_size * 3 / 4;
pOutVideoCodecCtx->rc_buffer_aggressivity = (float)1.0;
pOutVideoCodecCtx->rc_initial_cplx = 0.5;

测试表现:
ffmpeg 码率控制(总结篇)_第3张图片从测试表现来看,ffmpeg只能尽力保证单位时间内的码率为相同值,但存在轻微的波动。

VBR

VBR:Variable BitRate - 动态比特率

单位时间内的码率是可变的,使用VBR编码时,系统将自动为内容的简单部分分配较少的比特,从而留出足量的比特用于生成高质量的复杂部分。

对于复杂性恒定的内容(例如新闻播音)不会受益于VBR编码。对混合内容使用 VBR 编码时,在文件大小相同的条件下,VBR编码的输出结果要比CBR编码的输出结果质量好得多。在某些情况下,与CBR编码文件质量相同的VBR编码文件, 其大小可能只有前者的一半。

代码实现:

// VBR
pOutVideoCodecCtx->flags |= CODEC_FLAG_QSCALE;
pOutVideoCodecCtx->rc_min_rate = bitRate - 400000;
pOutVideoCodecCtx->rc_max_rate = bitRate + 400000;
pOutVideoCodecCtx->bit_rate = bitRate;

测试表现:
ffmpeg 码率控制(总结篇)_第4张图片从测试结果上看,VBR在传输时,码率确实会上下浮动。

ABR

ABR:Average Bitrate - 平均码率

平均比特率,是VBR的一种插值参数。Lame针对CBR不佳的文件体积比和VBR生成文件大小不定的特点独创了这种编码模式。ABR也 被称为“Safe VBR”,它是在指定的平均Bitrate内,以每50帧(30帧约1秒)为一段,低频和不敏感频率使用相对低的流量,高频和大动态表现时使用高流量。

代码实现:

// ABR
pOutVideoCodecCtx->bit_rate = 800000;

测试表现:
ffmpeg 码率控制(总结篇)_第5张图片从测试结果上看,ABR相对于VBR,码率更稳定一些。

H264编码控制

ffmpeg中采用H264,H265标准编码时,可能需要设置profilepresettune,ffmpeg中需要采用额外参数AVDictionary传入avcodec_open2()函数中实现。

profile

H.264有四种画质级别,分别是baseline, extended, main, high

profile取值 含义 释义
baseline 基本画质 支持I/P 帧,只支持无交错(Progressive)和CAVLC
extended 进阶画质 支持I/P/B/SP/SI 帧,只支持无交错(Progressive)和CAVLC(用的少)
main 主流画质 提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced),也支持CAVLC 和CABAC 的支持
high 高级画质 在main Profile 的基础上增加了8x8内部预测、自定义量化、 无损视频编码和更多的YUV 格式

H.264 baseline profile、extended profile和main profile都是针对8位样本数据、4:2:0格式(YUV)的视频序列。在相同配置情况下,high profile(HP)可以比main profile(MP)降低10%的码率。

根据应用领域的不同,Baseline profile多应用于实时通信领域,Main profile多应用于流媒体领域,High profile则多应用于广电和存储领域。

代码实现:

// profile
av_dict_set(&param, "profile", "main", 0);

preset

preset值 释义
ultrafast 极快
superfast 超快
veryfast 非常快
faster 更快
fast
medium
slow
slower 更慢
veryslow 非常慢
placebo 超慢

编码加快,意味着信息丢失越严重,输出图像质量越差。

他们之间的区别这取决于源材料,目标比特率和您的硬件配置。 通常,比特率越高,编码所需的时间越多。
这是一个示例,显示了1080p视频的两次通过编码的(标准化)编码时间:
ffmpeg 码率控制(总结篇)_第6张图片

从中到慢,所需时间增加了约40%。 相反,变慢会导致所需时间增加大约100%(将花费两倍的时间)。 与中等速度相比,veryslow需要原始编码时间的280%,而质量较慢的速度只有很少的改进。
使用快速可节省大约10%的编码时间,快则可节省25%。 超快将节省55%的成本,但质量要低得多。

代码实现:

// preset
av_dict_set(&param, "preset", "veryfast", 0);

如果未配置该选项,或者采取较慢的速度,会导致CPU消耗过大的问题。

tune

主要配合视频类型和视觉优化的参数况。如果视频的内容符合其中一个可用的调整值又或者有其中需要,则可以使用此选项,否则建议不使用(如tune grain是为高比特率的编码而设计的)。

tune值 释义
film 电影、真人类型
animation 动画
grain 需要保留大量的grain时用
stillimage 静态图像编码时使用
psnr 为提高psnr做了优化的参数
ssim 为提高ssim做了优化的参数
fastdecode 可以快速解码的参数
zerolatency 零延迟,用在需要非常低的延迟的情况下,比如电视电话会议的编码

代码实现:

// tune
av_dict_set(&param, "tune", "zerolatency", 0);

参考链接:
https://blog.csdn.net/owen7500/article/details/51832035
https://blog.csdn.net/DONGHONGBAI/article/details/84776431
https://www.cnblogs.com/tinywan/p/6402007.html
https://www.cnblogs.com/sunny-li/p/9979796.html
https://trac.ffmpeg.org/wiki/Encode/H.264

你可能感兴趣的:(ffmpeg,音视频)