ffmpeg多种码率控制方式的实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ffmpeg多种码率控制方式的实现
ffmpeg是我们进行视频编解码常用的工具,而对于ffmpeg中编码时对码率的控制方式一直没找合适的教程,无意中在stackoverflow 上发现了答案,在此进行总结备忘。
视频编码器常用的码率控制方式包括abr(平均码率),crf(限制码率),cqp(固定质量),ffmpeg中AVCodecContext显示提供了码率大小的控制参数,但是并没有提供其他的控制方式。
ffmpeg中码率控制方式分为以下几种情况:
1.如果设置了AVCodecContext中bit_rate的大小,则采用abr 的控制方式;
2.如果没有设置AVCodecContext中的bit_rate,则默认按照crf 方式编码,crf默认大小为23(此值类似于qp值,同样表示视频质量);
3.如果用户想自己设置,则需要借助av_opt_set函数设置AVCodecContext的priv_data参数。
下面给出三种控制方式的实现代码:
[cpp] view plain copy
print?
1........
2.int bpsValue; //码流控制方式的对应值
3.int bpsMode; //码流控制方式,0表示平均码率(abr),1表示固定码率(crf),2表示固定质量(cqp)
4.AVCodecContext* pCodecCtx;
5........
6.
7.//码率控制方式
8.string modeValue = int2String(bpsValue);
9.switch (bpsMode) {
10.case 0:
11.pCodecCtx->bit_rate = bpsValue*1000;
12.break;
13.case 1:
14.av_opt_set(pCodecCtx->priv_data,"crf",modeValue.c_s tr(),AV_OPT_SEARCH_CHILDREN);
15.break;
16.case 2:
17.av_opt_set(pCodecCtx->priv_data,"qp",modeValue.c_s tr(),AV_OPT_SEARCH_CHILDREN);
18.break;
19.default:
20.pCodecCtx->bit_rate = bpsValue;
21.break;
22.}
同时ffmpeg中采用H264,H265标准编码时,可能需要设置preset、tune和profile,ffmpeg中需要采用额外参数AVDictionary 传入avcodec_open2()函数中实现。
下面给出参考代码:[cpp] view plain copy
print?
1.//编码器预设
2.AVDictionary *dictParam = 0;
3.if(pCodecCtx->codec_id == AV_CODEC_ID_H264)
4.{
5.av_dict_set(&dictParam,"preset","medium",0);
6.av_dict_set(&dictParam,"tune","zerolatency",0);
7.av_dict_set(&dictParam,"profile","main",0);
8.}
9.
10.if(pCodecCtx->codec_id == AV_CODEC_ID_H265)
11.{
12.av_dict_set(&dictParam,"preset","ultrafast",0);
13.av_dict_set(&dictParam,"tune","zerolatency",0);
14.av_dict_set(&dictParam,"profile","main",0);
15.}
16.
17.//输出格式信息
18.av_dump_format(pFormatCtx, 0, outputFileName.c_str (), 1);
19.
20.pCodec = avcodec_find_encoder(pCodecCtx->codec_i
d);
21.if (!pCodec)
22.{
23.printf("没有找到合适的编码器!\n");
24.return false;
25.}
26.if (avcodec_open2(pCodecCtx, pCodec,&dictParam) < 0)
27.{
28.printf("编码器打开失败!\n");
29.return false;
30.}。