在编码器中,码率控制有两个重要的参数,1 时间基准 2 当前帧时间戳

一 为什么需要这两个

因为编码器的码率控制是以时间s为单位的,比如1000kbps,意思是1s有1000kbits的数据量,然后在编码器中并没有时间的概念,

只有时间基准和时间戳,这两个合并可以计算出来时间,所以编码器的码率控制都是以这两个参数为基础计算出来的。

时间基准:很多编码器设置的都是1/fps, 但是也有时候需要直接传入ms

为单位的帧pts,这样的话,时间基准就需要设置为1/1000, 还有如果像ts/mp4格式解码出来的视频帧,时间基准是1/90000,这样编码

的时候就设置成1/90000。

时间戳:当时间基准为1/fps时, 时间戳每次+1,依次递增,这样编码出来的帧之后,需要把时间戳scale为容器(flv,rtmp,mp4, ts等)需要的基准。

看下x264编码器中时间戳在码率控制中的作用。以下分析代码:

enum pic_struct_e

{

PIC_STRUCT_AUTO = 0, // automatically decide (default)

PIC_STRUCT_PROGRESSIVE = 1, // progressive frame

// "TOP" and "BOTTOM" are not supported in x264 (PAFF only)

PIC_STRUCT_TOP_BOTTOM = 4, // top field followed by bottom

PIC_STRUCT_BOTTOM_TOP = 5, // bottom field followed by top

PIC_STRUCT_TOP_BOTTOM_TOP = 6, // top field, bottom field, top field repeated

PIC_STRUCT_BOTTOM_TOP_BOTTOM = 7, // bottom field, top field, bottom field repeated

PIC_STRUCT_DOUBLE = 8, // double frame

PIC_STRUCT_TRIPLE = 9, // triple frame

};

这个枚举标示了一个帧需要占用多少个时间基准单元,这种是在设置的时间基准为1/fps,并且关闭了b_vfr_input的时候使用的。

b_vfr_input意思是变动帧率输入,这样编码器计算帧之间的duration, 直接用前后帧时间戳相减。见代码

h->lookahead->next.list[i]->i_duration = 2 * (h->lookahead->next.list[i+1]->i_pts - h->lookahead->next.list[i]->i_pts);

当b_vfr_input关闭的时候,时间基准需要被设置为1/fps, 要不然无法计算出帧duration。见代码

h->lookahead->next.list[i]->i_duration = delta_tfi_divisor[h->lookahead->next.list[i]->i_pic_struct];

delta_tfi_divisor是一个数组,预先设定了,某种类型的帧,duration为多少个时间基准单元。

接下来计算得到时间基准之后,开始用于码率控制。以crf码控为例

clip_qscale 为x264编码器中主要的帧级别的码控函数

double fenc_cpb_duration = (double)h->fenc->i_cpb_duration *
            h->sps->vui.i_num_units_in_tick / h->sps->vui.i_time_scale;

首先根据时间基准把duration换算成以秒为单位的时间。

total_duration += last_duration; //累加到当前编码帧的duration中,得到当前编码的总帧的duration,

通过总的编码帧duration以及

for( int j = 0; buffer_fill_cur >= 0 && buffer_fill_cur <= rcc->buffer_size; j++ )
{//先通过当前给定的qp值计算出来,需要消耗多少bits
 total_duration += last_duration;
buffer_fill_cur += rcc->vbv_max_rate * last_duration;
 int i_type = h->fenc->i_planned_type[j];
 int i_satd = h->fenc->i_planned_satd[j];
if( i_type == X264_TYPE_AUTO )
 break;
 i_type = IS_X264_TYPE_I( i_type ) ? SLICE_TYPE_I : IS_X264_TYPE_B( i_type ) ? SLICE_TYPE_B : SLICE_TYPE_P;
 cur_bits = predict_size( &rcc->pred[i_type], frame_q[i_type], i_satd );
buffer_fill_cur -= cur_bits;
last_duration = h->fenc->f_planned_cpb_duration[j];
}

然后按照当前的vbv码率控制给的参数计算出来,total_duration时长的帧最多能消耗多少bits

target_fill = X264_MIN( rcc->buffer_fill + total_duration * rcc->vbv_max_rate * 0.5, rcc->buffer_size * 0.5 );

然后比较这两,如果不足,就调大qp值。 qp的默认值为crf值

if( buffer_fill_cur < target_fill )
{
  q *= 1.01;
  terminate |= 1;
 continue;
 }

//VBV码率控制buf的限制,和上面的maxrate控制类似

target_fill = x264_clip3f( rcc->buffer_fill - total_duration * rcc->vbv_max_rate * 0.5, rcc->buffer_size * 0.8, rcc->buffer_size );
if( rcc->b_vbv_min_rate && buffer_fill_cur > target_fill )
 {
 q /= 1.01;
terminate |= 2;
 continue;
 }

最多调整1000次,最终得到一个合适的qp值。

x264码率控制-帧duration计算相关推荐

  1. X264码率控制流程分析

    码率控制的理论知识: 码率控制的目的和意义: 图像通信中码率控制的目的:通过调节编码参数,控制单位时间内的编码视频流的数据量,以使产生的比特流符合各种应用的需求.视频压缩的效率和视频内容有很大的关系, ...

  2. X264码率控制总结1——ABR,CQP,CRF

    lakeone X264码率控制总结1--ABR,CQP,CRF 1. X264显式支持的一趟码率控制方法有:ABR, CQP, CRF. 缺省方法是CRF.这三种方式的优先级是ABR > CQ ...

  3. 【Codecs系列】X264码率控制总结1——ABR,CQP,CRF

    X264码率控制总结1--ABR,CQP,CRF https://blog.csdn.net/chinabinlang/article/details/88837615

  4. 转: X264码率控制总结1——ABR,CQP,CRF

    2019独角兽企业重金招聘Python工程师标准>>> 1. X264显式支持的一趟码率控制方法有:ABR, CQP, CRF. 缺省方法是CRF.这三种方式的优先级是ABR > ...

  5. X264码率控制流程分析 (转)

    二.编码器机能20钟头前 码率节制的意见常识: 码率节制的目的以及意义: 图象通讯中码率节制的目的:路程经过过程调治编码参量,节制单元时间内的编码视频文件流的数值量,以使 ... 二.编码器机能20钟 ...

  6. x264中码率控制(一)

    x264码率控制方法:采用的码率控制算法并没有采用拉格朗日代价函数来控制编码,而是使用一种更简单的方法,即利用半精度帧的SATD(sum of absolute transformeddifferen ...

  7. x264中码率控制(二)x264_ratecontrol_start函数

    在一帧的编码前就选择QP值.帧层码率控制,到这一步,一帧中所有宏块还是统一qp的 void x264_ratecontrol_start( x264_t *h, int i_force_qp ) {x ...

  8. x264 码率控制算法原理

    x264 的码率控制是如何实现的 ? 本文介绍 x264 码率控制算法的数学原理,和基本框架. 1.理论假设 有助于往下阅读,可以暂时跳过. 设变量:      qscale = 拉格朗日常数 lam ...

  9. 阿里视频云黄海宇:解析世界杯超大规模直播场景下的码率控制

    在本月的重庆云栖大会飞天技术汇专场中,阿里云高级算法专家黄海宇分享了题为<超大规模直播码率控制>的议题,从生产的链路角度来说世界杯怎么让观众看到更加清晰的视频. 这一次的世界杯,与以往世界 ...

  10. 解析世界杯超大规模直播场景下的码率控制

    摘要: 这一次的世界杯,与以往世界杯最大的区别在于,有很多互联网用户观看直播,而不是在电视上.在互联网观看直播,互联网的网络条件不一样,观众会看不同码率的视频.所以主要分享下阿里云在直播中怎么做码率控 ...

最新文章

  1. LaTeX - 带圈数字
  2. 使用示例_在Unity中使用ComputeShader示例
  3. 高等数学:第十二章 微分方程(2)一阶线性非齐次微分方程、全微分方程、可降阶的微分方程
  4. Typora markdown公式换行等号对齐_Typora-编写博客格式化文档的最佳软件
  5. 创业冲突的五种解决方法是_当创业合伙人发生冲突时,最好的解决办法看这5招...
  6. electron 打包_Vue3+Electron整合方式
  7. jakarta ee_Jakarta EE,EE4J和Java EE之间的关系
  8. Spring Integration Publisher
  9. 《ArcGIS Runtime SDK for .NET开发笔记》--三维功能
  10. iOS取证将如漫漫长夜
  11. ViewPager和Tabhost结合,可滑动的tabhost
  12. 腾讯x5内核(TBS)简单集成封装
  13. MicroSIP注册点星PBX后拨打电话undefined external error故障解决方法
  14. 金蝶凭证序时簿在哪_怎么用金蝶kis记账王打开会计分录序时簿
  15. 提前实现盈利的快手还有多少成长空间?
  16. 墨画子卿第三章:初心第1节:上元灯会
  17. 完整Debian7配置LAMP(Apache/MySQL/PHP)环境及搭建建站
  18. 记忆翻牌游戏代码html,html5记忆翻牌游戏实现思路及代码
  19. 目标主机showmount -e信息泄露(CVE-1999-0554),如何禁止只允许特定主机使用showmount -e查看挂载列表
  20. linux ping等待时间,linux ping命令详解

热门文章

  1. js实现中文简体繁体转换
  2. 面试如何解释上份工作时间短
  3. 解决WebStorme点击谷歌浏览器图标无反应问题
  4. c盘python怎么移到d盘_怎样把C盘的所有文件移到D盘或E盘里去?
  5. Linux 音频编程 -- 如何使用ALSE库播放wav文件
  6. Premiere 常用视频概念
  7. 第4章第20节:异形图表:使用子母饼图制作人员组成表 [PowerPoint精美幻灯片实战教程]
  8. html中button标签reset用法
  9. JAVA Future类详解
  10. sublimetext text3比较两个文档的不同