文档章节

H.264参考软件JM12.2RC代码详细流程

雷霄骅
 雷霄骅
发布于 2014/08/16 13:59
字数 895
阅读 233
收藏 0
代码:JM12.2.编码结构:IPP。GOP:3.
跟踪代码:(注表示编码主流程,表示RC流程
----------------------------------------------------------------------------------------------
进入main() ,首先调用init_global_buffers().进入init_global_buffers(),调用两个函数generic_alloc( &generic_RC )//Dynamically allocate memory needed for generic rate control 和 rc_alloc( &quadratic_RC ) //Dynamically allocate memory needed for rate control。然后进入rc_init_seq(rc_quadratic *prc) //Initialize rate control parameters。这三个函数在整个流程中只调用一次。
----------------------------------------------------------------------------------------------
编码循环开始。调用rc_init_GOP(rc_quadratic *prc, int np, int nb) //Initialize one GOP。
----------------------------------------------------------------------------------------------
开始编码第一帧。I帧。
进入encode_one_frame(),调用rc_init_pict(rc_quadratic *prc, int fieldpic,int topfield,int targetcomputation, float mult) //Initialize one picture。接着调用updateQP(quadratic_RC, 0) //compute a quantization parameter for each frame.调用frame_picture() //Encodes a frame picture。进入frame_picture(), 调用code_a_picture()//Encodes a picture. 进入code_a_picture(),调用encode_one_slice() //Encodes one slice。进入encode_one_slice(),调用encode_one_macroblock() //Mode Decision for a macroblock, 进入encode_one_macroblock(),调用update_rc()//Update Rate Control Parameters,接着调用handle_qp(Macroblock *currMB, short best_mode) //Update QP Parameters (critical in case of SKIP MBs or MBAFF).
编码完一帧以后调用rc_update_pict_frame(rc_quadratic *prc, int nbits) //update after frame encoding。最后调用rc_update_pict(rc_quadratic *prc, int nbits) //update one picture after frame/field encoding.
第一帧I帧编码完成。
----------------------------------------------------------------------------------------------
开始编码第二帧。第一个P帧。
循环再次调用encode_one_frame()。现在编码的是P帧。调用rc_init_pict(),接着调用updateQP(),进入updateQP(),调用updateFirstP( rc_quadratic *prc, int topfield ) //计算第一个P帧的量化参数。调用frame_picture() 。进入frame_picture(), 调用code_a_picture() 。进入code_a_picture(),调用encode_one_slice() 。进入encode_one_slice(),对宏块进行编码循环。先调用start_macroblock(),如果已编码宏块数大于0并且是基本单元宏块数的整数倍,则调用updateRCModel (rc_quadratic *prc) //update the parameters of quadratic R-D model。进入updateRCModel(),调用QP2QStep(),接着调用两次RCModelEstimator()。之后调用updateMADModel然后调用updateQP()进入updateQP(),调用updateFirstP().然后调用encode_one_macroblock(), 进入encode_one_macroblock(),调用update_rc()接着调用handle_qp()
***需要注意的一点:对于第一个基本单元,进入updateRCModel之后,在调用完两次RCModelEstimator之后,没有调用updateMADModel。从第二个基本单元开始,才进入updateMADModel。进入updateMADModel以后,会调用MADModelEstimator。并且,编码第一个P帧时调用updateMADModel没有任何作用。只有在编码第二个P帧开始,updateMADModel才会起作用。***
编码完一帧以后调用rc_update_pict_frame。接着调用rc_update_pict().调用 updateRCModel(),进入updateRCModel(),调用两次RCModelEstimator()。之后调用updateMADModel。进入updateMADModel,这个时候updateMADModel函数会起作用了。它调用MADModelEstimator,更新参数之后并再次调用MADModelEstimator
第一个P帧编码完成。
----------------------------------------------------------------------------------------------
开始编码第三帧,即第二个P帧。
调用encode_one_frame()调用rc_init_pict(),接着调用updateQP(),进入updateQP(),由于是第一个基本单元,调用updateFirstBU( rc_quadratic *prc, int topfield )。之后调用frame_picture() 。进入frame_picture(), 调用code_a_picture() 。进入code_a_picture(),调用encode_one_slice() 。进入encode_one_slice(),对宏块进行编码循环。调用encode_one_macroblock(), 进入encode_one_macroblock(),调用update_rc()接着调用handle_qp()。编码的宏块数超过一个且是基本单元宏块数的整数倍时,调用在start_macroblock里面的updateRCModel。进入updateRCModel(),调用QP2QStep(),接着调用两次RCModelEstimator()。之后调用updateMADModel,进入updateMADModel,调用两次MADModelEstimator然后调用updateQP()。进入updateQP,如果Target<0,调用updateNegativeTarget( rc_quadratic *prc, int topfield, int m_Qp ),否则会:调用predictCurrPicMAD,接着调用updateModelQPBU(rc_quadratic *prc, int topfield, int m_Qp),如果是最后一个基本单元,则调用updateLastBU().
编码完一帧以后调用rc_update_pict_frame。接着调用rc_update_pict().调用 updateRCModel(),进入updateRCModel(),调用两次RCModelEstimator()。之后调用updateMADModel。进入updateMADModel,这个时候updateMADModel函数会起作用了。它调用MADModelEstimator,更新参数之后并再次调用MADModelEstimator
-----------------------------------------------------------------------------------------------------------------------------------
以上是我跟踪代码所得。比较简单,但是仍希望对大家有帮助


本文转载自:http://blog.csdn.net/leixiaohua1020/article/details/11980219

雷霄骅
粉丝 205
博文 419
码字总数 2129
作品 4
朝阳
程序员
私信 提问
将OBS录制数据通过RTMP协议引入到自己的程序中

最近在window是平台下,做了一功能实现通过OBS采集音视频,并通过RTMP协议将其编码压缩后的数据接入到自己的程序中来,因OBS软件自带有很强大的游戏录制和桌面录制的功能,以及输入、输出音频...

Gobert
2014/11/27
0
0
将OBS录制数据通过RTMP协议引入到自己的程序中

最近在window是平台下,做了一功能实现通过OBS采集音视频,并通过RTMP协议将其编码压缩后的数据接入到自己的程序中来,因OBS软件自带有很强大的游戏录制和桌面录制的功能,以及输入、输出音频...

IcedBeer
2016/11/03
53
0
[总结]视音频编解码技术零基础学习方法

一直想把视音频编解码技术做一个简单的总结,可是苦于时间不充裕,一直没能完成。今天有着很大的空闲,终于可以总结一个有关视音频技术的入门教程,可以方便更多的人学习从零开始学习视音频技...

leixiaohua1020
2014/06/16
0
0
让android支持RTSP及live555分析

#DATE 2012/05/09 #2012/08/27由cnblogs迁入 如何让Android支持C++异常机制 Android不支持C++异常机制,如果需要用到的话,则需要在编译的时候加入比较完整的C++库. Android支持的C++库可以在A...

Wii-D
2012/08/27
0
6
x264源代码简单分析:x264命令行工具(x264.exe)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leixiaohua1020/article/details/45583217 ===================================================== H.264源代......

雷霄骅
2015/05/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Node.js 多进程处理CPU密集任务

Node.js 单线程与多进程 大家都知道 Node.js 性能很高,是以异步事件驱动、非阻塞 I/O 而被广泛使用。但缺点也很明显,由于 Node.js 是单线程程序,如果长时间运算,会导致 CPU 不能及时释放...

Svend
31分钟前
0
0
Django笔记-3-模型-20190526

简介 django为各种数据库提供了很好的支持,django对这些数据库提供了统一的调用API;可以根据不同的也无需求选择不同的数据库; 配置数据库 在setting.py文件中配置数据库 DATABASES = { ...

Frank1126lin
46分钟前
3
0
OSChina 周日乱弹 —— 程序员做噩梦

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @-冰冰棒- :#今日歌曲推荐# 手嶌葵《Kiss The Girl》 《Kiss The Girl》- 手嶌葵 手机党少年们想听歌,请使劲儿戳(这里) @Sharon啊 :今天...

小小编辑
今天
170
11
Another app is currently holding the yum lock; waiting for it to exit...

Another app is currently holding the yum lock; waiting for it to exit... The other application is: PackageKit Memory : 153 M RSS (266 MB VSZ) Started: Thu Jul 12 00:03......

圣洁之子
今天
2
0
FastDateFormat 研究

FastDateFormat 对缓存的利用,其实就是用ConcurrentHashMap 做了一个map类型的缓存 public F getInstance(final String pattern, TimeZone timeZone, Locale locale) { Validate......

暗中观察
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部