x264源码解析:码率控制之能量函数
最近刚好看到有人问,所以会以码率控制为主线,陆续分享一些源码分析。
// 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源码解析:码率控制之能量函数相关推荐
- x264源码分析与应用示例(一)——视频编码基本流程
本文包含以下内容 1.H.264编码流程详述与对应x264源码解析 首先简单介绍一下x264源码调试与修改的基本方法.就是基本的conifigure和make,configure命令使用最简单的就可以 ...
- snabbdom源码解析(七) 事件处理
事件处理 我们在使用 vue 的时候,相信你一定也会对事件的处理比较感兴趣. 我们通过 @click 的时候,到底是发生了什么呢! 虽然我们用 @click绑定在模板上,不过事件严格绑定在 vnode ...
- redux 思考以及源码解析
1. 基本概念 redux有以下几个基本概念: 1.1. action action: 是一个对象,对一个行为的基本描述 {type:'add',todo } 1.2 action creator 一 ...
- DPDK之l3fwd-power源码解析
DPDK之l3fwd-power源码解析 引言 1 源码概述 1.1 关键变量 1.2 数据结构 2 源码解析 2.1 LEGACY模式 2.2 EMPTY_POLL模式 2.3 TELEMETRY模 ...
- Colly源码解析——结合例子分析底层实现
通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...
- VVeboTableView 源码解析
原文链接:http://www.jianshu.com/p/78027a3a2c41 最近在看一些 iOS 性能优化的文章,我找到了 VVeboTableView 这个框架.严格来说这个不属于框架,而 ...
- python处理回显_Python中getpass模块无回显输入源码解析
本文主要讨论了python中getpass模块的相关内容,具体如下. getpass模块 昨天跟学弟吹牛b安利Python标准库官方文档的时候偶然发现了这个模块.仔细一看内容挺少的,只有两个主要api ...
- spring aop 注入源码解析
spring aop 注入源码解析 aop启动 AbstractApplicationContext.java @Overridepublic void refresh() throws BeansE ...
- spring 注解试事物源码解析
spring 注解试事物源码解析 基于xml注解式事务入口 public class TxNamespaceHandler extends NamespaceHandlerSupport {stati ...
最新文章
- Python之路(第九篇)Python文件操作
- VC++软件工程师高端培训
- 虚拟主机上传SQLServer数据库--不完全资料
- 矢量切片_数据粒度均衡的二维矢量瓦片构建方法
- CSS一个冒号是伪类:用于监控动作、两个冒号是伪元素::用于定位元素
- ajax工具怎么安装,AJAX工具
- Oracle:select into 查询没有记录的解决办法
- python基础——错误处理
- SharpZipLib 压缩ZIP导出
- 转贴:Josephus问题
- 小程序如何添加外部字体库
- XP系统服务启动设置优化
- 苹果鼠标右键怎么按_IOS13.4更新后的鼠标用途在哪?
- Android 获取当天零点的毫秒值并将时间格式化
- Make sure that `gem install libv8 -v '3.16.14.3'` succeeds before bundling.
- AU入门音频编辑基本认识
- python自动剪视频_python剪切视频与合并视频的实现
- ArcGIS字段计算器中的python函数(转发)
- FPGA:三种基本门电路设计(与门、或门、非门)
- 国家信息系统安全等级保护基本要求——等保一级、二级、三级、四级内容