欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【十八】 H.266/VVC | VTM数据结构学习笔记

程序员文章站 2022-07-07 13:31:06
...

【十八】 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(统一建模语言)基本模型图

【十八】 H.266/VVC | VTM数据结构学习笔记


五、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

【十八】 H.266/VVC | VTM数据结构学习笔记
当cs2调用getCU{32,32}的时候,查询此位置是否是当前CodingStructure管理的CodingUnit,得到的结果是当前CodingStructure,于是返回此CodingUnit

【十八】 H.266/VVC | VTM数据结构学习笔记
当cs2调用getCU{16,32}的时候,查询此位置是否是当前CodingStructure管理的CodingUnit,得到的结果不是当前CodingStructure,于是自底向上去其父类CodingStructure中去寻找,找到后返回当前查询位置的CodingUnit

【十八】 H.266/VVC | VTM数据结构学习笔记
当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之间的一些关联

【十八】 H.266/VVC | VTM数据结构学习笔记


更多关于视频编码知识和资源的分享,更精致的文章排版,欢迎关注博主微信公众号,一起交流、学习、进步!!!
【十八】 H.266/VVC | VTM数据结构学习笔记

相关标签: VVC/H.266