HM编码器代码阅读(27)——样点自适应补偿SAO(一)SAO介绍以及入口函数
来源:互联网 发布:cms视频监控 解码 编辑:程序博客网 时间:2024/05/23 11:58
样点自适应补偿(SAO)
原理
介绍
SAO以CTU为基本单位,通过选择一个合适的分类器将冲击的像素划分类别,然后对不同类别像素使用不同的补偿值。SAO包括两大类的补偿方式:边界补偿(EO)和边带补偿(BO),此外,还引入了参数融合技术。
边界补偿EO
(1)波谷——种类1
(2)下坡波谷——种类2
(3)上坡波谷——种类2
(4)下坡波峰——种类3
(5)上坡波峰——种类3
(6)波峰——种类4
(7)其他的——种类0
对于种类1、2、3、4都需要进行补偿,对于种类0不进行补偿,同一种类的像素要使用相同的补偿值
边带补偿BO
在一定的图像区域内,像素值的波动范围很小,HEVC规定一个CTU只能选择4条连续的边带,并且只对属于这四个边带的像素进行补偿,选择哪4条边带可以通过率失真优化方法确定
SAO参数融合-merge
(1)直接使用左边的块
(2)直接使用上面的块
(3)通过分析自己像素块的特点,选择自己的参数(即使用EO或BO)
注意:一个CTU的亮度块和色度块分量必须同时使用左边或者上面的相邻块的补偿参数,否则使用EO或者BO
更多的信息请看 HEVC/H.265理论知识(7)——环路滤波
SAO的数据结构和枚举
// SAO所有的模式typedef enum{ SAO_MODE_OFF = 0, SAO_MODE_NEW, SAO_MODE_MERGE, NUM_SAO_MODES}SAOMode;
// SAO的merge模式的细分typedef enum{ SAO_MERGE_LEFT =0, SAO_MERGE_ABOVE, NUM_SAO_MERGE_TYPES}SAOModeMergeTypes;
// EO、BO的详细分类typedef enum{SAO_TYPE_START_EO =0,SAO_TYPE_EO_0 = SAO_TYPE_START_EO,SAO_TYPE_EO_90,SAO_TYPE_EO_135,SAO_TYPE_EO_45,SAO_TYPE_START_BO,SAO_TYPE_BO = SAO_TYPE_START_BO,NUM_SAO_NEW_TYPES}SAOModeNewTypes;
// 使用EO的时候,像素的分类typedef enum{SAO_CLASS_EO_FULL_VALLEY = 0,SAO_CLASS_EO_HALF_VALLEY = 1,SAO_CLASS_EO_PLAIN = 2,SAO_CLASS_EO_HALF_PEAK = 3,SAO_CLASS_EO_FULL_PEAK = 4,NUM_SAO_EO_CLASSES,}SAOEOClasses;
/*** sao的统计数据** 保存了CTU(或者像素块)中像素的统计信息*/struct SAOStatData //data structure for SAO statistics{Int64 diff[MAX_NUM_SAO_CLASSES];Int64 count[MAX_NUM_SAO_CLASSES];SAOStatData(){}~SAOStatData(){}Void reset(){::memset(diff, 0, sizeof(Int64)*MAX_NUM_SAO_CLASSES);::memset(count, 0, sizeof(Int64)*MAX_NUM_SAO_CLASSES);}const SAOStatData& operator=(const SAOStatData& src){::memcpy(diff, src.diff, sizeof(Int64)*MAX_NUM_SAO_CLASSES);::memcpy(count, src.count, sizeof(Int64)*MAX_NUM_SAO_CLASSES);return *this;}#if SAO_ENCODE_ALLOW_USE_PREDEBLOCKconst SAOStatData& operator+= (const SAOStatData& src){for(Int i=0; i< MAX_NUM_SAO_CLASSES; i++){diff[i] += src.diff[i];count[i] += src.count[i];}return *this;}#endif};
/*** 一个CTU分量的SAO参数信息*/struct SAOOffset{// SAO的模式:关闭,new(即EO或者BO),mergeInt modeIdc; //NEW, MERGE, OFF// 模式的细分:EO_0, EO_90, EO_135, EO_45, BO. MERGE: left, aboveInt typeIdc; //NEW: EO_0, EO_90, EO_135, EO_45, BO. MERGE: left, above// BO带的起始索引Int typeAuxInfo; //BO: starting band indexInt offset[MAX_NUM_SAO_CLASSES];SAOOffset();~SAOOffset();Void reset();const SAOOffset& operator= (const SAOOffset& src);};
/*** 一个CTU的SAO参数信息*/struct SAOBlkParam{SAOBlkParam();~SAOBlkParam();Void reset();const SAOBlkParam& operator= (const SAOBlkParam& src);SAOOffset& operator[](Int compIdx){ return offsetParam[compIdx];}private:// 三个分量的SAO信息SAOOffset offsetParam[NUM_SAO_COMPONENTS];};
SAO的主函数
HEVC中SAO的主函数是TEncSampleAdaptiveOffset::SAOProcess,它的工作流程如下:
1、调用getStatistics,收集图像中像素的统计信息,用于判断像素属于EO的哪个种类/BO的哪个边带对于图像中的每一个CTU:
(1)调用deriveLoopFilterBoundaryAvailibility,判断环路滤波是否允许跨越slice或者tile的边界,以此判断当前CTU的邻居是否可用
(2)对于三个颜色分量,分别调用getBlkStats,该函数是统计像素块中像素的特性,然后判断像素属于EO的哪一个种类
2、如果预先去方块滤波的标志为真,那么调用addPreDBFStatistics,这个函数的目的是在上一步的统计信息的基础上添加去方块滤波的一些统计信息
3、调用decidePicParams,判断像素块的三个颜色分量(Y、U、V)是否需要进行SAO操作
4、调用decideBlkParams,进行SAO处理。对于图像的每一个CTU,进行下面的处理:
(1)调用getMergeList,得到SAO的merge列表(这一步就是SAO的merge模式)
(2)按照下面的步骤分别处理EO、BO、Merge三种类型,然后选取出最优的一种
①如果是EO或者BO,那么调用deriveModeNewRDO,处理EO和BO的每一种模式,并选择最优的那种模式
②如果是merge,那么调用deriveModeMergeRDO,处理merge的每一种方式,选取最优的方式
③最后选择出所有模式中最优的那个
(3)利用最优的模式(EO、BO、Merge三者之一),调用reconstructBlkSAOParam和offsetCTU,对重建的CTU进行补偿
/*** SAO主函数*/Void TEncSampleAdaptiveOffset::SAOProcess(TComPic* pPic, Bool* sliceEnabled, const Double *lambdas#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK, Bool isPreDBFSamplesUsed#endif){TComPicYuv* orgYuv= pPic->getPicYuvOrg();TComPicYuv* resYuv= pPic->getPicYuvRec();m_lambda[SAO_Y]= lambdas[0]; m_lambda[SAO_Cb]= lambdas[1]; m_lambda[SAO_Cr]= lambdas[2];TComPicYuv* srcYuv = m_tempPicYuv;resYuv->copyToPic(srcYuv);srcYuv->setBorderExtension(false);srcYuv->extendPicBorder();//collect statistics// 收集像素块的统计信息,用于判断像素属于EO的那个种类/BO的哪个边带getStatistics(m_statData, orgYuv, srcYuv, pPic);#if SAO_ENCODE_ALLOW_USE_PREDEBLOCKif(isPreDBFSamplesUsed){addPreDBFStatistics(m_statData); // 添加去方块滤波的统计信息}#endif//slice on/off // 判断三个颜色分量是否需要进行SAOdecidePicParams(sliceEnabled, pPic->getSlice(0)->getDepth()); //block on/off SAOBlkParam* reconParams = new SAOBlkParam[m_numCTUsPic]; //temporary parameter buffer for storing reconstructed SAO parameters// SAO处理decideBlkParams(pPic, sliceEnabled, m_statData, srcYuv, resYuv, reconParams, pPic->getPicSym()->getSAOBlkParam());delete[] reconParams;}
- HM编码器代码阅读(27)——样点自适应补偿SAO(一)SAO介绍以及入口函数
- HM编码器代码阅读(45)——样点自适应补偿SAO(四)对重建像素进行补偿
- HM编码器代码阅读(44)——样点自适应补偿SAO(三)选取最优的SAO模式并确定补偿值
- HM编码器代码阅读(43)——样点自适应补偿SAO(二)收集像素块的统计信息
- HM编码器代码阅读(46)——SAO总结
- 样点自适应补偿(SAO)技术
- HEVC 样点自适应补偿(SAO)原理详解
- HEVC中SAO--自适应样点补偿 详细分析解读
- HEVC中SAO--自适应样点补偿 详细分析解读 .
- HEVC中SAO--自适应样点补偿 详细分析解读 .
- HEVC中SAO--自适应样点补偿 详细分析解读
- HEVC中SAO--自适应样点补偿 详细分析解读
- HEVC中SAO--自适应样点补偿 分析解读
- HEVC中SAO--自适应样点补偿 分析解读
- HEVC中SAO--自适应样点补偿 详细分析解读
- HEVC中SAO--自适应样点补偿 详细分析解读
- x265源码分析:sao.cpp 自适应样点补偿
- HM编码器代码阅读(17)——帧间预测之merge模式(一)Merge模式的介绍以及相关函数
- IOS网络请求之NSURLSession使用
- java中集合的基本添加删除操作
- Android SharedPreferences使用
- 算法介绍(2) 快速排序算法
- oracle常用DDL语句
- HM编码器代码阅读(27)——样点自适应补偿SAO(一)SAO介绍以及入口函数
- [BZOJ4216]Pig(分块)
- 使用拷贝构造函数的理由和作用【整理】
- Linux I/O复用之select函数详解
- CSS学习笔记9:清除浮动
- VTK修炼之道83:Pipeline管线执行模型
- POJ 3700 Missile Defence System 已被翻译
- Linux系统默默改变了人类世界的生活方式
- IDR_MAINFRAME字符串资源含义