ffmpeg多种码率控制方式的实现
2016-07-05 15:49
1821 查看
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参数。下面给出三种控制方式的实现代码:
.......
int bpsValue; //码流控制方式的对应值
int bpsMode; //码流控制方式,0表示平均码率(abr),1表示固定码率(crf),2表示固定质量(cqp)
AVCodecContext* pCodecCtx;
.......
//码率控制方式
string modeValue = int2String(bpsValue);
switch (bpsMode) {
case 0:
pCodecCtx->bit_rate = bpsValue*1000;
break;
case 1:
av_opt_set(pCodecCtx->priv_data,"crf",modeValue.c_str(),AV_OPT_SEARCH_CHILDREN);
break;
case 2:
av_opt_set(pCodecCtx->priv_data,"qp",modeValue.c_str(),AV_OPT_SEARCH_CHILDREN);
break;
default:
pCodecCtx->bit_rate = bpsValue;
break;
}
同时ffmpeg中采用H264,H265标准编码时,可能需要设置preset、tune和profile,ffmpeg中需要采用额外参数AVDictionary传入avcodec_open2()函数中实现。下面给出参考代码:
//编码器预设
AVDictionary *dictParam = 0;
if(pCodecCtx->codec_id == AV_CODEC_ID_H264)
{
av_dict_set(&dictParam,"preset","medium",0);
av_dict_set(&dictParam,"tune","zerolatency",0);
av_dict_set(&dictParam,"profile","main",0);
}
if(pCodecCtx->codec_id == AV_CODEC_ID_H265)
{
av_dict_set(&dictParam,"preset","ultrafast",0);
av_dict_set(&dictParam,"tune","zerolatency",0);
av_dict_set(&dictParam,"profile","main",0);
}
//输出格式信息
av_dump_format(pFormatCtx, 0, outputFileName.c_str(), 1);
pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
if (!pCodec)
{
printf("没有找到合适的编码器!\n");
return false;
}
if (avcodec_open2(pCodecCtx, pCodec,&dictParam) < 0)
{
printf("编码器打开失败!\n");
return false;
}
视频编码器常用的码率控制方式包括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参数。下面给出三种控制方式的实现代码:
.......
int bpsValue; //码流控制方式的对应值
int bpsMode; //码流控制方式,0表示平均码率(abr),1表示固定码率(crf),2表示固定质量(cqp)
AVCodecContext* pCodecCtx;
.......
//码率控制方式
string modeValue = int2String(bpsValue);
switch (bpsMode) {
case 0:
pCodecCtx->bit_rate = bpsValue*1000;
break;
case 1:
av_opt_set(pCodecCtx->priv_data,"crf",modeValue.c_str(),AV_OPT_SEARCH_CHILDREN);
break;
case 2:
av_opt_set(pCodecCtx->priv_data,"qp",modeValue.c_str(),AV_OPT_SEARCH_CHILDREN);
break;
default:
pCodecCtx->bit_rate = bpsValue;
break;
}
同时ffmpeg中采用H264,H265标准编码时,可能需要设置preset、tune和profile,ffmpeg中需要采用额外参数AVDictionary传入avcodec_open2()函数中实现。下面给出参考代码:
//编码器预设
AVDictionary *dictParam = 0;
if(pCodecCtx->codec_id == AV_CODEC_ID_H264)
{
av_dict_set(&dictParam,"preset","medium",0);
av_dict_set(&dictParam,"tune","zerolatency",0);
av_dict_set(&dictParam,"profile","main",0);
}
if(pCodecCtx->codec_id == AV_CODEC_ID_H265)
{
av_dict_set(&dictParam,"preset","ultrafast",0);
av_dict_set(&dictParam,"tune","zerolatency",0);
av_dict_set(&dictParam,"profile","main",0);
}
//输出格式信息
av_dump_format(pFormatCtx, 0, outputFileName.c_str(), 1);
pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
if (!pCodec)
{
printf("没有找到合适的编码器!\n");
return false;
}
if (avcodec_open2(pCodecCtx, pCodec,&dictParam) < 0)
{
printf("编码器打开失败!\n");
return false;
}
相关文章推荐
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- Managed Media Aggregation using Rtsp and Rtp
- [总结]FFMPEG视音频编解码零基础学习方法
- 利用Ffmpeg获得flv视频缩略图和视频时间的代码
- codeigniter教程之上传视频并使用ffmpeg转flv示例
- PHP使用ffmpeg给视频增加字幕显示的方法
- PHP+FFMPEG实现将视频自动转码成H264标准Mp4文件
- 快速解决Android平台移植ffmpeg的一些问题
- java调用ffmpeg实现视频转换的方法
- python+ffmpeg视频并发直播压力测试
- php使用ffmpeg向视频中添加文字字幕的实现方法
- [总结]FFMPEG视音频编解码零基础学习方法
- ffmpeg的headers设置
- ffmpeg从rtsp抓流存flv[c# NReco.VideoConverter flv]
- FFMPEG 从rtsp抓取流,转存为flv文件。C语言代码方式.
- CentOs 下安装 ffmpeg 以及添加 ogg 音频支持
- Linux 下ffmpeg视频转码实战一安装
- php使用ffmpeg向视频中添加文字字幕的实现方法
- php使用ffmpeg获取视频信息并截图的实现方法
- FFmpeg音视频编解码实践总结