织梦CMS - 轻松建站从此开始!

罗索

HEVC学习(二) —— HM的整体结构及一些基本概念

jackyhwei 发布于 2020-08-21 14:17 点击:次 
在刚开始看HM的时候,对着7个工程,可能有人会感到困惑,该从哪里看起呢?当然了,对于已经有一定代码量积累的人或者之前研究过H.264代码如JM的人来说,从何入手应该不成问题。但我写这
TAG: H265  HEVC  

在刚开始看HM的时候,对着7个工程,可能有人会感到困惑,该从哪里看起呢?当然了,对于已经有一定代码量积累的人或者之前研究过H.264代码如JM的人来说,从何入手应该不成问题。但我写这篇出来,一方面是自己做个总结,备忘,另一方面也是希望能够帮助刚刚入手HM的朋友。好了,不多废话,还是进入正题吧。

 

对于一个完整的HM解决方案来说,总共包含了7个工程:1. TAppCommon 2. TAppDecoder 3. TAppEncoder

4. TLibCommon 5. TLibDecoder 6. TLibEncoder 7. TLibVideoIO

 

其中,'T'代表'Test'(这一个的理解可能有误),'App'代表'Application',表明该工程主要包含一些应用函数,'Lib'代表'Library',表明该工程主要包含一些库函数,这里顺便提一下,应用函数与库函数的主要区别是:前者是面向用户的,主要是通过调用若干库函数实现更为丰富和复杂的功能,而后者是面向程序设计者的,或者说对用户是不可见的,它由程序设计者来实现,主要是对一些基本的功能进行底层设计与实现,对于用户来说,只关心这些库函数的接口以及如何调用,不需也不应该关心它的实现。'Common'表明该工程包含的一些函数是编码器和解码器共用的,'Decoder'表明该工程包含的函数是解码器使用的,而'Encoder'表明该工程包含的函数是编码器使用的。'VideoIO'工程主要是实现对YUV文件的读写操作。

 

在有了上述的认识以后,相信对如何入手代码有了更为明确的方向了。比如,如果你想看编码器的代码,则首先应该找到跟'Encoder'有关的工程,即'TAppEncoder'和'TLibEncoder'这两个,其次,对于跟踪代码来说,应该从main函数入手,道理是显然的,因为程序的入口函数就是main,既然如此,那么这些函数应该是在用户程序里了,即应该找到'TAppEncoder'这个工程。对于解码器来说,也是类似的,找到'TAppDecoder'这个工程,就可以开始从main函数开始你的解码之旅了微笑。这里顺便提一下,编码器和解码器的主函数分别在encmain.cpp和decmain.cpp中,相信光看源文件名都能看出来了。

 

最后,简单介绍下HM代码中关于变量、函数的命名规则,熟悉这些规则,有利于对代码更好的理解。

 

(1)类的命名:

一般来说,一个头文件只包含一个类的定义,文件名即为类名,且该类是属于哪个工程的,它的名字就以该工程的前几个字母开头,如类TAppEncTop,它就是以工程TAppEncoder的前7个字母开头,因此,从该类的名字,就能够看出该类是属于哪个工程的。

(2)变量的命名:

对于类的数据成员来说,一般以'm_'开头,即'member';对于全局变量来说,一般以'g_'开头,即'global'。

对于一般的变量(包含上述两种变量)来说,有如下命名规则:'p',该变量是指针类型,即'pointer',n个'p'则表明该指针为n级指针;'c',该变量是某个类的对象,即'class';'i',该变量是整型,即'int';'u',该变量是无符号型,即'unsigned';'h',该变量是字符型,这里不用'c'来代表'char’应该是为了避免跟前面的'class'冲突了;'b',该变量是布尔类型,即'bool’;'d',该变量是双精度浮点数,即'double';'f',该变量是单精度浮点数,即'float';'a',该变量是类组,即'array';'e',该变量是枚举类型,即'enum';'r',该变量是引用类型,等等。值得一提的是,不是每个变量的命名都满足这些规则,具体情况还是要具体分析的。但是,按照这些规则,80%以上的变量都能一眼看出它的特性来。

 

(3)函数的命名:

一般来说,对于一个类的成员函数来说,如果该函数的访问权限是'protected',则在其函数名前加上'x';但是,在我看代码过程中,有些'protected'的成员函数并没按照这个规则来命名,所以,这一条规则仅供参考。能够肯定的是,只要某个函数名字前有个'x',则该函数一定是某个类的protected成员函数。

 

说了这么多,举个具体实例来说明下吧:

在工程TLibEncoder的头文件TEncCu.h中,定义了一个类TEncCu,有个数据成员m_ppcBestCU,根据前面的命名规则,它首先是个数据成员,是个二级指针,且是指向一个类的,实际上,它是这么声明的,TComDataCU**,TComDataCU它就是一个类,且该变量被声明为二级指针,据此,符合上述命名规则。

还有一个数据成员这么声明UChar                   m_uhTotalDepth; 无符号字符型,同样也是符合命名规则的。

在该类中,有这么一个成员函数xCompressCU,以'x'开头命名,在类中被声明为'protected',符合命名规则。

 

还有许多诸如此类的例子,在实际看代码的过程中,大家可以一条条去验证,如果发现我里面有哪些地方说的不对或者不够全面的,欢迎批评指正。

(HEVC_CJL)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/202008/17735.html]
本文出处:CSDN博客 作者:HEVC_CJL 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容