【十八】 H.266/VVC | VTM数据结构学习笔记
一、HM的缺陷
1、复杂的数据结构
- Z索引
- 不明确的数据模型(TComDateCU)
2、槽糕的代码可读性
- 复杂的内存操作与一般的数据流混杂在一起
- 缺乏数据和逻辑封装
3、复杂的可扩展性
- 数据结构的设计由严格的假设(例如:方块)
- 很多的想法因为扩展性的复杂而被放弃
二、VTM的设计原则
1、简单明确的数据模型:采用现代O-O设计原则,快速且前言
2、全局像素寻址
- 消除Z索引的使用
- 消除2级(CUT->Z索引)信号寻址
3、简单操作的封装(例如:内存操作):允许一般流程更好的可读性
4、更好的代码可读性:允许更容易的可扩展性
三、HM中重要的数据结构
1、TComDateCU
- 存储编码信息
- 可能表示一个CU或者CTU(一个CTU包含多个CU)
- 图像位置到编码信息的映射
2、TComTU
- 允许更简单的TU结构导航的对象
- 不包含实际数据,而是包裹在TComDateCU的周围
3、TComPicYuv
- 存储视频信号
【注意】:在VVC的测试模型VTM中,上面三种数据结构全部被弃用,提出了一些新的数据结构
四、VVC中各种信号的存储
1、导航(索引)信息
- Size、Position、Area(其中 Area = Position + Size):表示基本的二维索引信息
- CompArea:给定一个分量(块)的面积
- UnitArea:表示多通道信号中的一个面积;描述同位分量的组成的块的集合
2、信号存储(包含在CommonLib中的Buffer.h文件中)
-
AreaBuf:结构体模板
- 描述二维信号在一维内存中的排版
- 包含简单的操作(复制、填充等)
-
UnitAreaBuf
- 描述多分量二维信号在一维内存中的排版
- 包含简单的操作(复制、填充等)
-
PelStorage:一个分配了内存的UnitAreaBuf
3、编码信息
-
Picture:包含输入输出信号还有元数据(Slice信息等)
-
CodingUnit、PredictionUnit、TransformUnit
- 单一单元的单一对象
- 包含对应的信息
- 包含位置信息(由UnitArea推导而来)
-
CodingStucture
- 管理CodingUnit,将它们和Picture相关联
- 包含用于从上至下的RD搜索的附加的函数
4、各种数据结构的UML(统一建模语言)基本模型图
五、VTM的细节描述
1、CodingStructure的基础知识
- 包含CodingUnit等对象,将它们映射到图像中
- HM中TComDateCU的替代,但是是全局变量
- Top-Level的CodingStructure包含一帧中所有的CU、PU和TU
- Sub-Level的CodingStructure包含一个指定对象的UnitArea的表示
- 在构建后是空的,需要填充
- addCU/PU/TU方法构建并且映射到特定的对象
- getCU/PU/TU获取特定的对象的地址,通过使用全局Position
- 动态分配所需的资源(内存)
- 使用dynamic_cache提高性能
2、使用CodingStructure进行RD_Search
-
专为自上而下的方法设计
-
允许使用“透明的”全局上下文进行本地测试编码
- 遵循众所周知的向上传播的最佳临时方案
-
分层级联
- 一个CodingStructure被设置去表达一个局部的UnitArea
- 这个UnitArea之外的将转发到父类CodingStructure
-
父节点不知道子节点
- 最好的候选者需要向上传给父节点
六、分层级联的CodingStructure
当cs2调用getCU{32,32}的时候,查询此位置是否是当前CodingStructure管理的CodingUnit,得到的结果是当前CodingStructure,于是返回此CodingUnit
当cs2调用getCU{16,32}的时候,查询此位置是否是当前CodingStructure管理的CodingUnit,得到的结果不是当前CodingStructure,于是自底向上去其父类CodingStructure中去寻找,找到后返回当前查询位置的CodingUnit
当cs1调用getCU{32,32}的时候,查询此位置是否是当前CodingStructure管理的CodingUnit,得到的结果是当前CodingStructure,由于其无法得知其子节点的信息,所以返回了一个空指针
七、划分(Partitioner)
- 一个简单的类来管理划分(CU和TU或者别的可能的类)
- 作为堆栈建模,在当前处理区域上创建新的划分作为Level(级别)
- 对于HEVC来说
- 包含了当前划分的一个访问器
- 深度(CU/TU)以及实际当前的UnitArea
- 对于二叉树、四叉树(BTQT)以及其他的特性(HEVC特性除外)来说
- 允许设置划分的限制(例如在一个确定的级别上限制划分)
- 允许执行划分的合理性检查
八、数据的谱系关系(Date Ownership)
- 每个数据都属于一个对象,并需要分配内存并释放内存
- Picture
- 归属于EncLib或者DecLib
- 拥有信号的缓冲区、Slice对象、SEI消息和TileMap
- AreaBuf、UnitBuf
- 不保存任何数据
- PelStorage
- 可能拥有某些缓冲区,取决于创建的时候是Creat还是CreatFromBuf
- 拥有的数据保存在m_origin成员变量中
- CodingStructure
- Top_Layer:属于Picture,连接至图像的信号缓冲区,但不拥有这些缓冲区
- Other(暂时存在于RD_Search):属于EncCU或者IntraSearch ,包含一些信号的缓冲区,并拥有它们
- 总是拥有描述结构和布局的缓冲区(不是幸好偶)
- 拥有变化系数缓冲区
- 不拥有CodingUnit,仅仅是dynamic_cache链接到它们
- CodingUnit、PredictionUnit、TransformUnit
- 属于dynamic_cache,其中对象时通过get获取,通过cache来释放
- TransformUnit
- 不拥有变换系数缓冲区
- 从CodingStructure链接到缓冲区
- dynamic_cache
- Top_Level的缓冲区是全局的(在运行时动态分配,并在退出的时候释放)
- RD_Search的缓冲区是属于EnCU和IntraSearch
九、代码片段
在一个CU中迭代所有的TUs(帧间解码的例子)
- 对PUs的迭代调用和traversePU(…)相似
- 当CU只包含了一个TU或者PU的时候,firstTU和firstPU可以被作为快速访问器
//对CU中所描述的所有TUs调用xDecodeInterTU
for(auto& currTU: CU::traverseTUs(cu))
{
xDecodeInterTU(currTU compID );
}
十、常见的问题
运动信息保存在哪里?
- 最初使用HEVC,运动矢量存储的最小分辨率是PU
- 针对h.266标准最新提出的工具打破了这一常规(VCEG-AZ10)
- 运动矢量信息需要Sub-PU分辨率
- 将Sub-PU存储为PUs将会破坏提出的PU逻辑
- 解决方案:为子PU解析的运动信息增加缓冲区
- 例子:
Mv mvL0 cs getPU pos mv 0 ]; // 过时的low-res(低分辨率)调用
Mv mvL0 cs getMotionInfo pos mv 0 ];];// 新的下一代风格的high-res(高分辨率)调用
- 旧的调用还在允许,可能会提供子分辨率的结果
- PU::spanMotionInfo方法设定了这个缓冲区
十一、标准软件的参考
1、Size、Position、Area
- Size
- width,heigh:UInt—描述了一个矩形的大小
- Position
- x,y:Int—描述了一个点的二维位置信息
- Area:Size,Position
- 继承自Size和Position,一个位于特定位置的特定大小的矩形
- CompArea:Area
- 一个多分量信号的特定分量的(CompID)Area
2、UnitArea、CodingUnit、PredictionUnit、TransformUnit
- UnitArea
- block[0……N-1]:CompArea
- N个多分量信号的blocks的融合
- CodingUnit:UnitArea
- 描述如何对单元区域所描述的区域进行编码
- PredictionUnit:UnitArea
- 描述如何生成这个单元区域的预测信号
- TransformUnit:UnitArea
- 描述如何应用这个单位区域的转换编码
3、AreaBuf
- AreaBuf < T > (定义了Pel和TCoeff为PelArea和CoeffAreaBuf)
- at(x,y):返回信号在(x,y)处的值
- buf(x,y):返回一个指向(x,y)位置的缓冲区的未加工(raw)的指针
- subBuf(x,y,w,h):返回一个AreaBuf,描述距离(x,y)偏移量为(w,h)的位置的缓冲区
- fill(val):使用特定的值填充特定的区域
- copyFrom(other):从别的区域将内容复制过来
- substract,addVag,reconstruct,removeHighFreg:取代TComYuv功能的方法
- UnitBuf< T >,与AreaBuf有着相似的接口
- bufs[0……N-1]:AreaBuf,包含了信号不同分量的说明
4、CodingStructure Basics
- CodingStructure Basics
- area:UnitArea类型,描述了CodingStructure跨越了图像的哪些区域
- addCU(UnitArea):创建并定位跨越了UnitArea的CodingUnit
- getCU(Position):返回位于指定位置的CodingUnit(TransformUnit和Prediction存在模拟接口)
- setDeComp(CompArea):设置指定位置的CompArea以重建
- setDeComp(UnitArea):模拟多通道的操作
- isDeComp(Position):返回这个位置的重建信号是否已经被生成
5、RD-Search with CodingStructure
- CodingStructure
- initStructDate(……):清除当前包含的所有数据(信号和编码信息)
- initSubStructure(……):将一个新的CodingStructure连接到下一层
- useSubStructure(……):从子结构中赋值编码数据
- copyStructure(……):从其他结构中复制编码信息,并不受到父子之间的约束关系
十二、HM与VTM之间的一些关联
更多关于视频编码知识和资源的分享,更精致的文章排版,欢迎关注博主微信公众号,一起交流、学习、进步!!!