HM编码器代码阅读(43)——样点自适应补偿SAO(二)收集像素块的统计信息
来源:互联网 发布:mac系统语言代码 编辑:程序博客网 时间:2024/06/06 17:03
收集像素块的统计信息
在进行SAO之前,要对像素块的像素值进行归类,然后判断它们属于EO的那个种类或者BO的哪个边带
入口函数getStatistics
getStatistics是收集像素统计信息的入口函数
流程如下:
1、遍历图像的每一个CTU
2、对于每一个CTU,调用deriveLoopFilterBoundaryAvailibility,用来判断相邻CTU的有效性(是否存在)
3、对于每个CTU的每一个颜色分量,调用getBlkStats,用来搜集该CTU中某个分量的像素的统计信息
4、处理结束
/*** 收集像素块的统计信息,用于判断像素属于EO的那个种类/BO的哪个边带** 对整个图像进行处理,遍历图像的每一个CTU,对CTU的每一个分量,都调用 getBlkStats*/Void TEncSampleAdaptiveOffset::getStatistics(SAOStatData*** blkStats, TComPicYuv* orgYuv, TComPicYuv* srcYuv, TComPic* pPic#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK, Bool isCalculatePreDeblockSamples#endif){Bool isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail;for(Int ctu= 0; ctu < m_numCTUsPic; ctu++){Int yPos = (ctu / m_numCTUInWidth)*m_maxCUHeight;Int xPos = (ctu % m_numCTUInWidth)*m_maxCUWidth;Int height = (yPos + m_maxCUHeight > m_picHeight)?(m_picHeight- yPos):m_maxCUHeight;Int width = (xPos + m_maxCUWidth > m_picWidth )?(m_picWidth - xPos):m_maxCUWidth;// 判断相邻CTU的有效性(是否存在)pPic->getPicSym()->deriveLoopFilterBoundaryAvailibility(ctu, isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail);//NOTE: The number of skipped lines during gathering CTU statistics depends on the slice boundary availabilities.//For simplicity, here only picture boundaries are considered.isRightAvail = (xPos + m_maxCUWidth < m_picWidth );isBelowAvail = (yPos + m_maxCUHeight < m_picHeight);isBelowRightAvail = (isRightAvail && isBelowAvail);isBelowLeftAvail = ((xPos > 0) && (isBelowAvail));isAboveRightAvail = ((yPos > 0) && (isRightAvail));for(Int compIdx=0; compIdx< NUM_SAO_COMPONENTS; compIdx++){Bool isLuma = (compIdx == SAO_Y);Int formatShift= isLuma?0:1;Int srcStride = isLuma?srcYuv->getStride():srcYuv->getCStride();Pel* srcBlk = getPicBuf(srcYuv, compIdx)+ (yPos >> formatShift)*srcStride+ (xPos >> formatShift);Int orgStride = isLuma?orgYuv->getStride():orgYuv->getCStride();Pel* orgBlk = getPicBuf(orgYuv, compIdx)+ (yPos >> formatShift)*orgStride+ (xPos >> formatShift);// 搜集一个CTU中某个分量的像素的统计信息getBlkStats(compIdx, blkStats[ctu][compIdx] , srcBlk, orgBlk, srcStride, orgStride, (width >> formatShift), (height >> formatShift), isLeftAvail, isRightAvail, isAboveAvail, isBelowAvail, isAboveLeftAvail, isAboveRightAvail, isBelowLeftAvail, isBelowRightAvail#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK, isCalculatePreDeblockSamples#endif);}}}
判断相邻CTU的有效性
deriveLoopFilterBoundaryAvailibility用于判断相邻CTU的有效性(是否存在),这是为了下一步的像素统计做准备
/*** 判断相邻CTU的有效性(是否存在)*/Void TComPicSym::deriveLoopFilterBoundaryAvailibility(Int ctu,Bool& isLeftAvail,Bool& isRightAvail,Bool& isAboveAvail,Bool& isBelowAvail,Bool& isAboveLeftAvail,Bool& isAboveRightAvail,Bool& isBelowLeftAvail,Bool& isBelowRightAvail){isLeftAvail = (ctu % m_uiWidthInCU != 0);isRightAvail = (ctu % m_uiWidthInCU != m_uiWidthInCU-1);isAboveAvail = (ctu >= m_uiWidthInCU );isBelowAvail = (ctu < m_uiNumCUsInFrame - m_uiWidthInCU);isAboveLeftAvail = (isAboveAvail && isLeftAvail);isAboveRightAvail= (isAboveAvail && isRightAvail);isBelowLeftAvail = (isBelowAvail && isLeftAvail);isBelowRightAvail= (isBelowAvail && isRightAvail);Bool isLoopFiltAcrossTilePPS = getCU(ctu)->getSlice()->getPPS()->getLoopFilterAcrossTilesEnabledFlag();{TComDataCU* ctuCurr = getCU(ctu);TComDataCU* ctuLeft = isLeftAvail ?getCU(ctu-1):NULL;TComDataCU* ctuRight = isRightAvail?getCU(ctu+1):NULL;TComDataCU* ctuAbove = isAboveAvail?getCU(ctu-m_uiWidthInCU):NULL;TComDataCU* ctuBelow = isBelowAvail?getCU(ctu+m_uiWidthInCU):NULL;TComDataCU* ctuAboveLeft = isAboveLeftAvail ? getCU(ctu-m_uiWidthInCU-1):NULL;TComDataCU* ctuAboveRigtht= isAboveRightAvail? getCU(ctu-m_uiWidthInCU+1):NULL;TComDataCU* ctuBelowLeft = isBelowLeftAvail ? getCU(ctu+m_uiWidthInCU-1):NULL;TComDataCU* ctuBelowRight = isBelowRightAvail? getCU(ctu+m_uiWidthInCU+1):NULL;{//leftif(ctuLeft != NULL){isLeftAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuLeft->getSlice()->getSliceCurStartCUAddr())?ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag():true;}//aboveif(ctuAbove != NULL){isAboveAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuAbove->getSlice()->getSliceCurStartCUAddr())?ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag():true;}//rightif(ctuRight != NULL){isRightAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuRight->getSlice()->getSliceCurStartCUAddr())?ctuRight->getSlice()->getLFCrossSliceBoundaryFlag():true;}//belowif(ctuBelow != NULL){isBelowAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuBelow->getSlice()->getSliceCurStartCUAddr())?ctuBelow->getSlice()->getLFCrossSliceBoundaryFlag():true;}//above-leftif(ctuAboveLeft != NULL){isAboveLeftAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuAboveLeft->getSlice()->getSliceCurStartCUAddr())?ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag():true;}//below-rightif(ctuBelowRight != NULL){isBelowRightAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuBelowRight->getSlice()->getSliceCurStartCUAddr())?ctuBelowRight->getSlice()->getLFCrossSliceBoundaryFlag():true;}//above-rightif(ctuAboveRigtht != NULL){Int curSliceStartEncOrder = ctuCurr->getSlice()->getSliceCurStartCUAddr();Int aboveRigthtSliceStartEncOrder = ctuAboveRigtht->getSlice()->getSliceCurStartCUAddr();isAboveRightAvail = (curSliceStartEncOrder == aboveRigthtSliceStartEncOrder)?(true):((curSliceStartEncOrder > aboveRigthtSliceStartEncOrder)?(ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag()):(ctuAboveRigtht->getSlice()->getLFCrossSliceBoundaryFlag())); }//below-leftif(ctuBelowLeft != NULL){Int curSliceStartEncOrder = ctuCurr->getSlice()->getSliceCurStartCUAddr();Int belowLeftSliceStartEncOrder = ctuBelowLeft->getSlice()->getSliceCurStartCUAddr();isBelowLeftAvail = (curSliceStartEncOrder == belowLeftSliceStartEncOrder)?(true):((curSliceStartEncOrder > belowLeftSliceStartEncOrder)?(ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag()):(ctuBelowLeft->getSlice()->getLFCrossSliceBoundaryFlag()));} }if(!isLoopFiltAcrossTilePPS){ isLeftAvail = (!isLeftAvail ) ?false:(getTileIdxMap( ctuLeft->getAddr() ) == getTileIdxMap( ctu ));isAboveAvail = (!isAboveAvail ) ?false:(getTileIdxMap( ctuAbove->getAddr() ) == getTileIdxMap( ctu ));isRightAvail = (!isRightAvail ) ?false:(getTileIdxMap( ctuRight->getAddr() ) == getTileIdxMap( ctu ));isBelowAvail = (!isBelowAvail ) ?false:(getTileIdxMap( ctuBelow->getAddr() ) == getTileIdxMap( ctu ));isAboveLeftAvail = (!isAboveLeftAvail ) ?false:(getTileIdxMap( ctuAboveLeft->getAddr() ) == getTileIdxMap( ctu ));isAboveRightAvail= (!isAboveRightAvail) ?false:(getTileIdxMap( ctuAboveRigtht->getAddr() ) == getTileIdxMap( ctu ));isBelowLeftAvail = (!isBelowLeftAvail ) ?false:(getTileIdxMap( ctuBelowLeft->getAddr() ) == getTileIdxMap( ctu ));isBelowRightAvail= (!isBelowRightAvail) ?false:(getTileIdxMap( ctuBelowRight->getAddr() ) == getTileIdxMap( ctu ));}}}
搜集一个CTU分量的像素的统计信息
getBlkStats用来搜集一个CTU中某个分量的像素的统计信息
流程如下:
1、遍历SAO除了merge之外的所有模式:SAO_TYPE_EO_0、SAO_TYPE_EO_90、SAO_TYPE_EO_135、SAO_TYPE_EO_45、SAO_TYPE_BO
2、对于每一个SAO模式,都统计该模式下像素的信息
3、最后的统计信息存放在SAOStatData中
/*** 搜集一个CTU中某个分量的像素的统计信息** 遍历SAO除了merge之外的所有类型:** SAO_TYPE_EO_0 ,** SAO_TYPE_EO_90,** SAO_TYPE_EO_135,** SAO_TYPE_EO_45,** SAO_TYPE_BO ** 对于每一种类型,都搜集像素的统计信息** 最后的统计信息存放在SAOStatData中*/Void TEncSampleAdaptiveOffset::getBlkStats(Int compIdx, SAOStatData* statsDataTypes , Pel* srcBlk, Pel* orgBlk, Int srcStride, Int orgStride, Int width, Int height, Bool isLeftAvail, Bool isRightAvail, Bool isAboveAvail, Bool isBelowAvail, Bool isAboveLeftAvail, Bool isAboveRightAvail, Bool isBelowLeftAvail, Bool isBelowRightAvail#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK, Bool isCalculatePreDeblockSamples#endif){if(m_lineBufWidth != m_maxCUWidth){m_lineBufWidth = m_maxCUWidth;if (m_signLineBuf1) delete[] m_signLineBuf1; m_signLineBuf1 = NULL;m_signLineBuf1 = new Char[m_lineBufWidth+1]; if (m_signLineBuf2) delete[] m_signLineBuf2; m_signLineBuf2 = NULL;m_signLineBuf2 = new Char[m_lineBufWidth+1];}Int x,y, startX, startY, endX, endY, edgeType, firstLineStartX, firstLineEndX;Char signLeft, signRight, signDown;Int64 *diff, *count;Pel *srcLine, *orgLine;Int* skipLinesR = m_skipLinesR[compIdx];Int* skipLinesB = m_skipLinesB[compIdx];for(Int typeIdx=0; typeIdx< NUM_SAO_NEW_TYPES; typeIdx++){SAOStatData& statsData= statsDataTypes[typeIdx];statsData.reset();srcLine = srcBlk;orgLine = orgBlk;diff = statsData.diff;count = statsData.count;switch(typeIdx){case SAO_TYPE_EO_0:{diff +=2;count+=2;endY = (isBelowAvail) ? (height - skipLinesB[typeIdx]) : height;#if SAO_ENCODE_ALLOW_USE_PREDEBLOCKstartX = (!isCalculatePreDeblockSamples) ? (isLeftAvail ? 0 : 1): (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1));#elsestartX = isLeftAvail ? 0 : 1;#endif#if SAO_ENCODE_ALLOW_USE_PREDEBLOCKendX = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1)): (isRightAvail ? width : (width - 1));#elseendX = isRightAvail ? (width - skipLinesR[typeIdx]): (width - 1);#endiffor (y=0; y<endY; y++){#if SAO_SGN_FUNCsignLeft = (Char)sgn(srcLine[startX] - srcLine[startX-1]);#elsesignLeft = (Char)m_sign[srcLine[startX] - srcLine[startX-1]];#endiffor (x=startX; x<endX; x++){#if SAO_SGN_FUNCsignRight = (Char)sgn(srcLine[x] - srcLine[x+1]);#elsesignRight = (Char)m_sign[srcLine[x] - srcLine[x+1]]; #endifedgeType = signRight + signLeft;signLeft = -signRight;diff [edgeType] += (orgLine[x] - srcLine[x]);count[edgeType] ++;}srcLine += srcStride;orgLine += orgStride;}#if SAO_ENCODE_ALLOW_USE_PREDEBLOCKif(isCalculatePreDeblockSamples){if(isBelowAvail){startX = isLeftAvail ? 0 : 1;endX = isRightAvail ? width : (width -1);for(y=0; y<skipLinesB[typeIdx]; y++){#if SAO_SGN_FUNCsignLeft = (Char)sgn(srcLine[startX] - srcLine[startX-1]);#elsesignLeft = (Char)m_sign[srcLine[startX] - srcLine[startX-1]];#endiffor (x=startX; x<endX; x++){#if SAO_SGN_FUNCsignRight = (Char)sgn(srcLine[x] - srcLine[x+1]);#elsesignRight = (Char)m_sign[srcLine[x] - srcLine[x+1]];#endifedgeType = signRight + signLeft;signLeft = -signRight;diff [edgeType] += (orgLine[x] - srcLine[x]);count[edgeType] ++;}srcLine += srcStride;orgLine += orgStride;}}}#endif}break;case SAO_TYPE_EO_90:// 代码省略...break;case SAO_TYPE_EO_135:// 代码省略...break;case SAO_TYPE_EO_45:// 代码省略...break;case SAO_TYPE_BO:// 代码省略...break;default:{printf("Not a supported SAO types\n");assert(0);exit(-1);}}}}
0 0
- HM编码器代码阅读(43)——样点自适应补偿SAO(二)收集像素块的统计信息
- HM编码器代码阅读(45)——样点自适应补偿SAO(四)对重建像素进行补偿
- HM编码器代码阅读(27)——样点自适应补偿SAO(一)SAO介绍以及入口函数
- HM编码器代码阅读(44)——样点自适应补偿SAO(三)选取最优的SAO模式并确定补偿值
- HM编码器代码阅读(46)——SAO总结
- 样点自适应补偿(SAO)技术
- HM编码器代码阅读(36)——帧内预测(三)帧内预测之参考像素块的预处理和滤波
- HM编码器代码阅读(31)——帧间预测之AMVP/Merge模式(六)运动补偿
- HEVC 样点自适应补偿(SAO)原理详解
- HM编码器代码阅读(10)——片的编码
- HM编码器代码阅读(11)——CU的初始化
- HM编码器代码阅读(22)——cabac的流程
- HM编码器代码阅读(41)——码率控制(二)
- HM编码器代码阅读(9)——片编码器的初始化
- HM编码器代码阅读
- HEVC中SAO--自适应样点补偿 详细分析解读
- HEVC中SAO--自适应样点补偿 详细分析解读 .
- HEVC中SAO--自适应样点补偿 详细分析解读 .
- fastboot写入boot文件
- Scala:简单使用Actor的消息发送与接收求和
- 原生js实现导航栏点击之后添加样式
- MongoDB限制内网访问的方法 Linux限制IP 端口
- 安卓notification点击后如何不走onCreate方法
- HM编码器代码阅读(43)——样点自适应补偿SAO(二)收集像素块的统计信息
- Monkey测试实际Native Crash问题的分析与解决思路
- android adb 启动activity、service,发送broadcast等操作
- 说说IO(一)- IO的分层
- html css 小计
- Android 全局监听判断有无网络
- BannerLayout的使用
- 说说IO(二)- IO模型
- rails中path和url有什么区别