ffmpeg多种码率控制方式的实现

转载:http://blog.csdn.net/owen7500/article/details/51832035

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参数。下面给出三种控制方式的实现代码:

  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_str(),AV_OPT_SEARCH_CHILDREN);  
  15.     break;  
  16. case 2:  
  17.     av_opt_set(pCodecCtx->priv_data,”qp”,modeValue.c_str(),AV_OPT_SEARCH_CHILDREN);  
  18.     break;  
  19. default:  
  20.     pCodecCtx->bit_rate = bpsValue;  
  21.     break;  
  22. }  
    .......
    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()函数中实现。下面给出参考代码:

  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_id);  
  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.  }  
   //编码器预设
    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;
    }



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值