最近刚好看到有人问,所以会以码率控制为主线,陆续分享一些源码分析。

// Find the total AC energy of the block in all planes.
//! 返回宏块的能量
static NOINLINE uint32_t x264_ac_energy_mb( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame )
{/* This function contains annoying hacks because GCC has a habit of reordering emms* and putting it after floating point ops.  As a result, we put the emms at the end of the* function and make sure that its always called before the float math.  Noinline makes* sure no reordering goes on. */uint32_t var;x264_prefetch_fenc( h, frame, mb_x, mb_y );if( h->mb.b_adaptive_mbaff ){/* We don't know the super-MB mode we're going to pick yet, so* simply try both and pick the lower of the two. */uint32_t var_interlaced, var_progressive;var_interlaced   = ac_energy_plane( h, mb_x, mb_y, frame, 0, 0, 1, 1 );var_progressive  = ac_energy_plane( h, mb_x, mb_y, frame, 0, 0, 0, 0 );if( CHROMA444 ){var_interlaced  += ac_energy_plane( h, mb_x, mb_y, frame, 1, 0, 1, 1 );var_progressive += ac_energy_plane( h, mb_x, mb_y, frame, 1, 0, 0, 0 );var_interlaced  += ac_energy_plane( h, mb_x, mb_y, frame, 2, 0, 1, 1 );var_progressive += ac_energy_plane( h, mb_x, mb_y, frame, 2, 0, 0, 0 );}else{var_interlaced  += ac_energy_plane( h, mb_x, mb_y, frame, 1, 1, 1, 1 );var_progressive += ac_energy_plane( h, mb_x, mb_y, frame, 1, 1, 0, 0 );}var = X264_MIN( var_interlaced, var_progressive );}else        ///<{var  = ac_energy_plane( h, mb_x, mb_y, frame, 0, 0, PARAM_INTERLACED, 1 );        // 亮度if( CHROMA444 ){var += ac_energy_plane( h, mb_x, mb_y, frame, 1, 0, PARAM_INTERLACED, 1 );var += ac_energy_plane( h, mb_x, mb_y, frame, 2, 0, PARAM_INTERLACED, 1 );}elsevar += ac_energy_plane( h, mb_x, mb_y, frame, 1, 1, PARAM_INTERLACED, 1 );    // 色度}x264_emms();return var;
}
//! 返回宏块亮度或色度分量的能量
static ALWAYS_INLINE uint32_t ac_energy_plane( x264_t *h, int mb_x, int mb_y, x264_frame_t *frame, int i, int b_chroma, int b_field, int b_store )
{int height = b_chroma ? 16>>CHROMA_V_SHIFT : 16;int stride = frame->i_stride[i];int offset = b_field? 16 * mb_x + height * (mb_y&~1) * stride + (mb_y&1) * stride: 16 * mb_x + height * mb_y * stride;stride <<= b_field;if( b_chroma ){ALIGNED_ARRAY_N( pixel, pix,[FENC_STRIDE*16] );int chromapix = h->luma2chroma_pixel[PIXEL_16x16];      // 420: 8x8int shift = 7 - CHROMA_V_SHIFT;                         // 420: 6h->mc.load_deinterleave_chroma_fenc( pix, frame->plane[1] + offset, stride, height );return ac_energy_var( h->pixf.var[chromapix]( pix,               FENC_STRIDE ), shift, frame, 1, b_store )+ ac_energy_var( h->pixf.var[chromapix]( pix+FENC_STRIDE/2, FENC_STRIDE ), shift, frame, 2, b_store );}elsereturn ac_energy_var( h->pixf.var[PIXEL_16x16]( frame->plane[i] + offset, stride ), 8, frame, i, b_store );
}

h->pixf.var分别获取亮度和色度分量的ssd与sum
对于yuv420:亮度分量16x16,色度分量是8x8
对于yuv444:亮度分量16x16,色度分量是16x16

//! 返回分量i的能量
static ALWAYS_INLINE uint32_t ac_energy_var( uint64_t sum_ssd, int shift, x264_frame_t *frame, int i, int b_store )
{   //! 64bit结果分解为32bit ssd, 32bit sumuint32_t sum = sum_ssd;uint32_t ssd = sum_ssd >> 32;if( b_store ){frame->i_pixel_sum[i] += sum;frame->i_pixel_ssd[i] += ssd;}return ssd - ((uint64_t)sum * sum >> shift);      // ssd - sum * avg
}
//! 按照32bit ssd | 32bit sum返回
static uint64_t x264_pixel_var_16x16( pixel *pix, intptr_t i_stride )
{                                             uint32_t sum = 0, sqr = 0;                for( int y = 0; y < 16; y++ )              {                                         for( int x = 0; x < 16; x++ )          {                                     sum += pix[x];                    sqr += pix[x] * pix[x];           }                                     pix += i_stride;                      }                                         return sum + ((uint64_t)sqr << 32);       ///< 32bit sqr + 32bit sum
}

x264源码解析:码率控制之能量函数相关推荐

  1. x264源码分析与应用示例(一)——视频编码基本流程

    本文包含以下内容 1.H.264编码流程详述与对应x264源码解析 首先简单介绍一下x264源码调试与修改的基本方法.就是基本的conifigure和make,configure命令使用最简单的就可以 ...

  2. snabbdom源码解析(七) 事件处理

    事件处理 我们在使用 vue 的时候,相信你一定也会对事件的处理比较感兴趣. 我们通过 @click 的时候,到底是发生了什么呢! 虽然我们用 @click绑定在模板上,不过事件严格绑定在 vnode ...

  3. redux 思考以及源码解析

    1. 基本概念 redux有以下几个基本概念: 1.1. action action: 是一个对象,对一个行为的基本描述 {type:'add',todo } 1.2 action creator 一 ...

  4. DPDK之l3fwd-power源码解析

    DPDK之l3fwd-power源码解析 引言 1 源码概述 1.1 关键变量 1.2 数据结构 2 源码解析 2.1 LEGACY模式 2.2 EMPTY_POLL模式 2.3 TELEMETRY模 ...

  5. Colly源码解析——结合例子分析底层实现

    通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...

  6. VVeboTableView 源码解析

    原文链接:http://www.jianshu.com/p/78027a3a2c41 最近在看一些 iOS 性能优化的文章,我找到了 VVeboTableView 这个框架.严格来说这个不属于框架,而 ...

  7. python处理回显_Python中getpass模块无回显输入源码解析

    本文主要讨论了python中getpass模块的相关内容,具体如下. getpass模块 昨天跟学弟吹牛b安利Python标准库官方文档的时候偶然发现了这个模块.仔细一看内容挺少的,只有两个主要api ...

  8. spring aop 注入源码解析

    spring aop 注入源码解析 aop启动 AbstractApplicationContext.java @Overridepublic void refresh() throws BeansE ...

  9. spring 注解试事物源码解析

    spring 注解试事物源码解析 基于xml注解式事务入口 public class TxNamespaceHandler extends NamespaceHandlerSupport {stati ...

最新文章

  1. Python之路(第九篇)Python文件操作
  2. VC++软件工程师高端培训
  3. 虚拟主机上传SQLServer数据库--不完全资料
  4. 矢量切片_数据粒度均衡的二维矢量瓦片构建方法
  5. CSS一个冒号是伪类:用于监控动作、两个冒号是伪元素::用于定位元素
  6. ajax工具怎么安装,AJAX工具
  7. Oracle:select into 查询没有记录的解决办法
  8. python基础——错误处理
  9. SharpZipLib 压缩ZIP导出
  10. 转贴:Josephus问题
  11. 小程序如何添加外部字体库
  12. XP系统服务启动设置优化
  13. 苹果鼠标右键怎么按_IOS13.4更新后的鼠标用途在哪?
  14. Android 获取当天零点的毫秒值并将时间格式化
  15. Make sure that `gem install libv8 -v '3.16.14.3'` succeeds before bundling.
  16. AU入门音频编辑基本认识
  17. python自动剪视频_python剪切视频与合并视频的实现
  18. ArcGIS字段计算器中的python函数(转发)
  19. FPGA:三种基本门电路设计(与门、或门、非门)
  20. 国家信息系统安全等级保护基本要求——等保一级、二级、三级、四级内容

热门文章

  1. ava.util.ConcurrentModificationException 异常
  2. JSP爱心宠物诊所系统设计与实现
  3. kafka入门介绍「详细教程」
  4. WiFi以及天线测试项目详解
  5. 服务器×××上的MSDTC不可用
  6. win10的bat文件或者cmd文件关联了文本编辑器导致无法运行
  7. 【ACWing】1278. 树的统计
  8. admin和xadmin的用法
  9. mac设置端口号转发到默认端口80、443
  10. 图像,log处理的一点经验