作者:66

1. 理论部分--快速率失真计算方法:

在后面的代码中用到了,在此说明一下方便后面的理解:

率失真(J) = 像素误差(D)+语法编码代价(λR),R是编码所需bit,λ是系数。

其中像素误差可以有MSE(最小均方误差)、MAD(最小平均绝对误差)等。这里用的MSE,即原始像素与重构像素的差值平方和。

以org代表原始像素,rec代表重构像素,offset为补偿值,则有:

补偿前:

补偿后:

补偿前后的误差:

上式中N为像素个数,因此率失真差值为:

可以看出计算差值J比计算J少了约N次对差值进行平方的计算,因此选最优时只需要对比差值J即可。

2.补充:

昨天剩下的两个函数,saoCOmponentParamDist中,计算过EO、BO模式后的merge与mergeup是计算取邻块SAO模式的率失真,也就是说,函数saoComponentParamDist计算并记录了EO、BO模式下最优模式,但并未在此函数中与融合模式进行对比,具体的对比在调用saoCOmponentParamDist的函数rdoSaoUnitAll的后半部分。

图一、本文涉及的代码结构(标红部分)

saoCOmponentParamDist中计算merge率失真的代码:

 // merge left or merge upfor (Int idxNeighbor=0;idxNeighbor<2;idxNeighbor++){saoLcuParamNeighbor = NULL;if (allowMergeLeft && addrLeft>=0 && idxNeighbor ==0)//!< 左邻块可用{saoLcuParamNeighbor = &(saoParam->saoLcuParam[yCbCr][addrLeft]);//!< 取左邻块的SAO参数}else if (allowMergeUp && addrUp>=0 && idxNeighbor ==1)//!< 上邻块可用{saoLcuParamNeighbor = &(saoParam->saoLcuParam[yCbCr][addrUp]);//!< 取上邻块的SAO参数}if (saoLcuParamNeighbor!=NULL){estDist = 0;typeIdx = saoLcuParamNeighbor->typeIdx;//取邻块的SAO模式if (typeIdx>=0){Int mergeBandPosition = (typeIdx == SAO_BO)?saoLcuParamNeighbor->subTypeIdx:0;Int   merge_iOffset;for(classIdx = 0; classIdx < m_iNumClass[typeIdx]; classIdx++){merge_iOffset = saoLcuParamNeighbor->offset[classIdx];estDist   += estSaoDist(m_iCount [yCbCr][typeIdx][classIdx+mergeBandPosition+1], merge_iOffset, m_iOffsetOrg[yCbCr][typeIdx][classIdx+mergeBandPosition+1],  shift);}}else{estDist = 0;}copySaoUnit(&compSaoParam[idxNeighbor], saoLcuParamNeighbor );compSaoParam[idxNeighbor].mergeUpFlag   = idxNeighbor;compSaoParam[idxNeighbor].mergeLeftFlag = !idxNeighbor;compDistortion[idxNeighbor+1] += ((Double)estDist/lambda);}}}

其中调用了计算率失真的函数estSaoDist,函数定义为:

inline Int64 TEncSampleAdaptiveOffset::estSaoDist(Int64 count, Int64 offset, Int64 offsetOrg, Int shift){return (( count*offset*offset-offsetOrg*offset*2 ) >> shift);}

这个函数用的是SAO率失真的快速计算方法,其中return (( count*offset*offset-offsetOrg*offset*2 ) >> shift);对应于公式

具体解析看前理论部分。

前面说过,merge模式参与率失真的比较在rdoSaoUnitAll函数后半部分,下面贴后半部分代码:

 //计算亮度和色度模式下的参数融合率失真if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] ){// Cost of new SAO_params初始化参数m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);m_pcRDGoOnSbacCoder->resetBits();if (allowMergeLeft){m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0);}if (allowMergeUp){m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0);}for ( compIdx=0;compIdx<3;compIdx++){if( (compIdx ==0 && saoParam->bSaoFlag[0]) || (compIdx >0 && saoParam->bSaoFlag[1])){m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);//cost of merge}}rate = m_pcEntropyCoder->getNumberOfWrittenBits();bestCost = compDistortion[0] + (Double)rate;m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);//计算参数融合模式下的率失真for(Int mergeUp=0; mergeUp<2; ++mergeUp){if ( (allowMergeLeft && (mergeUp==0)) || (allowMergeUp && (mergeUp==1)) ){m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);m_pcRDGoOnSbacCoder->resetBits();if (allowMergeLeft){m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(1-mergeUp);}if ( allowMergeUp && (mergeUp==1) ){m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(1);}rate = m_pcEntropyCoder->getNumberOfWrittenBits();//码率mergeCost = compDistortion[mergeUp+1] + (Double)rate;//率失真if (mergeCost < bestCost)//更新最佳滤波模式{bestCost = mergeCost;m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);              for ( compIdx=0;compIdx<3;compIdx++){mergeSaoParam[compIdx][mergeUp].mergeLeftFlag = 1-mergeUp;mergeSaoParam[compIdx][mergeUp].mergeUpFlag = mergeUp;if( (compIdx==0 && saoParam->bSaoFlag[0]) || (compIdx>0 && saoParam->bSaoFlag[1])){copySaoUnit(&saoParam->saoLcuParam[compIdx][addr], &mergeSaoParam[compIdx][mergeUp] );             }}}}}#if SAO_ENCODING_CHOICE#if SAO_ENCODING_CHOICE_CHROMAif( saoParam->saoLcuParam[0][addr].typeIdx == -1)//Y分量不存在SAO参数{numNoSao[0]++;}if( saoParam->saoLcuParam[1][addr].typeIdx == -1)//CbCr分量不存在SAO参数{numNoSao[1]+=2;}#elsefor ( compIdx=0;compIdx<3;compIdx++){if( depth == 0 && saoParam->saoLcuParam[compIdx][addr].typeIdx == -1){numNoSao++;}}#endif#endifm_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[0][CI_CURR_BEST]);}//!< if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )}//!< for (idxX = 0; idxX< frameWidthInCU; idxX++)}//!< for (idxY = 0; idxY< frameHeightInCU; idxY++)#if SAO_ENCODING_CHOICE#if SAO_ENCODING_CHOICE_CHROMAif( !saoParam->bSaoFlag[0]){m_depthSaoRate[0][depth] = 1.0;}else{m_depthSaoRate[0][depth] = numNoSao[0]/((Double) frameHeightInCU*frameWidthInCU);}if( !saoParam->bSaoFlag[1]){m_depthSaoRate[1][depth] = 1.0;}else{m_depthSaoRate[1][depth] = numNoSao[1]/((Double) frameHeightInCU*frameWidthInCU*2);}#elseif( depth == 0){// update SAO Ratem_depth0SaoRate = numNoSao/((Double) frameHeightInCU*frameWidthInCU*3);}#endif#endif}

(转载请注明出处)

SAO代码解析补充(二)相关推荐

  1. Tensorflow2.0---SSD网络原理及代码解析(二)-锚点框的生成

    Tensorflow2.0-SSD网络原理及代码解析(二)-锚点框的生成 分析完SSD网络的原理之后,一起来看看代码吧~ 代码转载于:https://github.com/bubbliiiing/ss ...

  2. Linux0.00 代码解析(二)

    Linux 0.00 的编译.运行.源码下载: http://blog.csdn.net/longintchar/article/details/78757065 Linux 0.00 Makefil ...

  3. OpenFOAM-v2006重叠网格挖洞问题研究以及overset代码解析(二)PATCH是什么类型的patch?

    上一篇的结尾提出了3个问题.回答这些问题能帮助我理解OpenFOAM重叠网格的执行过程. 首先我们来看第一个问题:PATCH对应哪一类patch? 看到cellCellStencil.H文件,里面有P ...

  4. 专题一:欧拉视频放大(线性)------MATLAB代码解析(二.amplify_spatial_lpyr_temporal_iir())

    目录 代码及其注释 理解 代码及其注释 function amplify_spatial_lpyr_temporal_iir(vidFile, resultsDir, ...alpha, lambda ...

  5. FAST-LIO2.0代码解析(二)preprocess.cpp

    不时会对其中的错误和模糊之处进行更新,未来会把完整的更新在gitee里 #include "preprocess.h"#define RETURN0 0x00 #define RE ...

  6. Linux-0.00 代码解析(四)

    Linux 0.00 的编译.运行.源码下载: http://blog.csdn.net/longintchar/article/details/78757065 Linux 0.00 Makefil ...

  7. “基于医疗知识图谱的问答系统”代码解析(一)

    "基于医疗知识图谱的问答系统"代码解析(一) build_medicalgraph.py -建立医疗知识图谱的代码解析 "基于医疗知识图谱的问答系统"代码解析( ...

  8. YOLOv3:Darknet代码解析(四)结构更改与训练

    背景:我们需要降低YOLOv2-tiny的参数量和存储量,以便硬件实现. 目的:更改YOLO结构,去掉后面的两层卷积层,降低参数量和运算量. 相关文章: YOLOv3:Darknet代码解析(一)安装 ...

  9. LOAM学习-代码解析(三)特征点运动估计 laserOdometry

    LOAM学习-代码解析(三)特征点运动估计 laserOdometry 前言 一.初始化 二.去除位移畸变 TransformToStart TransformToEnd 三.去除角度畸变 Plugi ...

  10. Tensorflow 代码解析

    Tensorflow 代码解析(一) Tensorflow 代码解析(二) Tensorflow 代码解析(三) Tensorflow 代码解析(四) Tensorflow 代码解析(五)

最新文章

  1. 【Python基础】Python的深浅拷贝讲解
  2. oracle查询表的字段类型有哪些,oracle中查询表的信息,包括表名,字段名,字段类型,主键(精)...
  3. SVN工具的使用 和在Eclipse中安装GPD插件:(多步审批流,因此选择使用工作流(JBPM)来实现)...
  4. Star PDF Watermark Ultimate中文版
  5. 残差网络ResNet笔记
  6. javaweb学习总结(二十八)——JSTL标签库之核心标签
  7. SDWebImage实现分析
  8. 小齐是如何提高自己的「编程能力」的?
  9. count函数_计数函数Count、Counta、Countblank、Countif、Countifs技巧解读
  10. 【报告分享】罗兰贝格2019年关于人工智能的十个议题.pdf(附下载链接)
  11. [转载] [转载] python中的Numpy库入门
  12. vue中的组件重定向
  13. 三菱电机NC monitor 序列号申请
  14. 现代工程制图及计算机辅助绘图答案,现代工程制图(附习题集第2版高等学校应用型特色规划教材)...
  15. WIFI智能音箱技术方案开发
  16. jsBlob数据转为图片
  17. 我的Java学习之路
  18. 用鸿蒙开发AI应用(五)HDF 驱动补光灯
  19. 推荐一款好用解压RAR、ZIP文件Mac软件,可以输入密码Dr. Unarchiver
  20. 电子杂志制作与设计教程全集

热门文章

  1. Sensor信号输出YUV、RGB、RAW DATA、JPEG 4种方式区别---转
  2. Kettle下载与安装教程【保姆版】
  3. matlab电子类元件库仿真元件,matlab电力系统仿真元件.doc
  4. linux 系统调试工具,Linux 系统调试...
  5. pyhive 安装sasl
  6. 开发APP需要什么技术?
  7. 【JAVA】java代码实现print2Flash转swf文件,百度文库一样。
  8. 急需能临时发邮件的临时邮箱 临时邮箱怎么注册 邮箱163注册入口在哪
  9. 计算机软考高级科目试题及答案,软考高级哪个含金量高 2018计算机软考信息系统项目管理师单选试题及答案...
  10. 下载excel 导入模板