Changeset 408 in 3DVCSoftware for branches/HTM-6.2-dev1-LG/source/Lib
- Timestamp:
- 16 May 2013, 09:23:44 (12 years ago)
- Location:
- branches/HTM-6.2-dev1-LG/source/Lib
- Files:
-
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HTM-6.2-dev1-LG/source/Lib/TLibCommon/ContextTables.h
r332 r408 101 101 #define NUM_ALF_SVLC_CTX 3 ///< number of context models for ALF SVLC (filter coeff.) 102 102 103 #if LGE_SAO_MIGRATION_D0091 104 #define NUM_SAO_MERGE_FLAG_CTX 1 ///< number of context models for SAO merge flags 105 #define NUM_SAO_TYPE_IDX_CTX 1 ///< number of context models for SAO type index 106 #else 103 107 #define NUM_SAO_FLAG_CTX 1 ///< number of context models for SAO flag 104 108 #define NUM_SAO_UVLC_CTX 2 ///< number of context models for SAO UVLC … … 108 112 #define NUM_SAO_MERGE_UP_FLAG_CTX 1 ///< number of context models for AO SVLC (filter coeff.) 109 113 #define NUM_SAO_TYPE_IDX_CTX 2 ///< number of context models for AO SVLC (filter coeff.) 114 #endif 110 115 #define CNU 154 ///< dummy initialization value for unused context models 'Context model Not Used' 111 116 … … 376 381 { 141, 154, 159, }, 377 382 }; 378 383 #if LGE_SAO_MIGRATION_D0091 384 static const UChar 385 INIT_SAO_MERGE_FLAG[3][NUM_SAO_MERGE_FLAG_CTX] = 386 { 387 { 153, }, 388 { 153, }, 389 { 153, }, 390 }; 391 392 static const UChar 393 INIT_SAO_TYPE_IDX[3][NUM_SAO_TYPE_IDX_CTX] = 394 { 395 { 200, }, 396 { 185, }, 397 { 160, }, 398 }; 399 #else 379 400 static const UChar 380 401 INIT_SAO_FLAG[3][NUM_SAO_FLAG_CTX] = … … 424 445 { 200, 140, }, 425 446 }; 447 #endif 426 448 427 449 static const UChar -
branches/HTM-6.2-dev1-LG/source/Lib/TLibCommon/TComDataCU.cpp
r384 r408 95 95 } 96 96 } 97 97 #if LGE_VSP_INHERIT_D0092 98 inline Bool TComDataCU::xAddVspMergeCand( UChar ucVspMergePos, UInt uiDepth, Bool* abCandIsInter, Int& iCount, 99 UChar* puhInterDirNeighbours, TComMvField* pcMvFieldNeighbours, Int* iVSPIndexTrue, Int mrgCandIdx, DisInfo* pDInfo ) 100 #else 98 101 inline Bool TComDataCU::xAddVspMergeCand( UChar ucVspMergePos, Int vspIdx, Bool* bVspMvZeroDone, UInt uiDepth, Bool* abCandIsInter, Int& iCount, 99 102 UChar* puhInterDirNeighbours, TComMvField* pcMvFieldNeighbours, Int* iVSPIndexTrue, Int mrgCandIdx, DisInfo* pDInfo ) 103 #endif 100 104 { 101 105 #if MTK_D0156 … … 115 119 if( ucVspMergePos == VSP_MERGE_POS ) 116 120 { 121 #if !LGE_VSP_INHERIT_D0092 117 122 Int idx = vspIdx - 1; 118 { 123 #endif 124 { 125 #if LGE_VSP_INHERIT_D0092 126 if( getSlice()->getSPS()->getViewId() != 0 ) 127 #else 119 128 if( getSlice()->getSPS()->getViewId() != 0 && bVspMvZeroDone[idx] == false ) 129 #endif 120 130 { 121 131 { 122 132 abCandIsInter [iCount] = true; 133 #if !LGE_VSP_INHERIT_D0092 123 134 bVspMvZeroDone[idx] = true; 135 #endif 124 136 125 137 // get Inter Dir … … 130 142 puhInterDirNeighbours[iCount] = 1; 131 143 #endif 144 #if LGE_VSP_INHERIT_D0092 145 Int iRefIdx = NOT_VALID; 146 #if QC_BVSP_CleanUP_D0191 147 iRefIdx = getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC()==getSlice()->getPOC() ? 0: getSlice()->getNewRefIdx(REF_PIC_LIST_0); 148 #endif 149 pcMvFieldNeighbours[iCount<<1].setMvField(pDInfo->m_acMvCand[0], iRefIdx ); 150 if ( getSlice()->isInterB() ) 151 { 152 pcMvFieldNeighbours[(iCount<<1)+1].setMvField( pDInfo->m_acMvCand[0], iRefIdx ); 153 } 154 iVSPIndexTrue[iCount] = 1; 155 #else 132 156 // get Mv using checked disparity vector 133 157 if (vspIdx < 4) // spatial … … 140 164 } 141 165 iVSPIndexTrue[idx] = iCount; 166 #endif 142 167 if ( mrgCandIdx == iCount ) 143 168 { … … 3626 3651 this->getPartPosition(uiPUIdx, xP, yP, nPSW, nPSH); 3627 3652 3628 #if MERL_VSP_C0152 3653 #if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092 3629 3654 Bool bVspMvZeroDone[3] = {false, false, false}; 3630 3655 #endif … … 3732 3757 } 3733 3758 } 3734 #if MERL_VSP_C0152 && !QC_BVSP_CleanUP_D0191 3759 #if MERL_VSP_C0152 && !QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092 3735 3760 xInheritVspMode( pcTextureCU, uiPartIdxCenter, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo ) ; 3736 3761 #endif … … 3797 3822 #if MERL_VSP_COMPENSATION_C0152 3798 3823 //===== vsp 0 ===== 3824 #if LGE_VSP_INHERIT_D0092 3825 if ( !xAddVspMergeCand(0, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 3826 #else 3799 3827 if( iCount < 4 + extraMergeCand ) 3800 3828 if ( !xAddVspMergeCand(0, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 3829 #endif 3801 3830 return; 3802 3831 #endif … … 3817 3846 { 3818 3847 if ( pcCULeft && !pcCULeft->isIntra( uiLeftPartIdx ) 3819 #if MERL_VSP_C0152 3848 #if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092 3820 3849 CHECK_ADD_YET(pcCULeft, uiLeftPartIdx, 1) 3821 3850 #endif … … 3866 3895 #endif 3867 3896 #if MERL_VSP_C0152 3897 #if LGE_VSP_INHERIT_D0092 3898 if (pcCULeft->getVSPIndex(uiLeftPartIdx)==1) 3899 { 3900 iVSPIndexTrue[iCount] = 1; 3901 } 3902 #else 3868 3903 xInheritVspMode( pcCULeft, uiLeftPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo 3869 3904 #if QC_BVSP_CleanUP_D0191 … … 3871 3906 #endif 3872 3907 ) ; 3908 #endif 3873 3909 #endif 3874 3910 if ( mrgCandIdx == iCount ) … … 3883 3919 } 3884 3920 3921 #if MERL_VSP_COMPENSATION_C0152 3922 //===== vsp 1 ===== 3923 #if LGE_VSP_INHERIT_D0092 3924 if ( !xAddVspMergeCand(1, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 3925 #else 3926 if( iCount < 4 + extraMergeCand ) 3927 if ( !xAddVspMergeCand(1, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 3928 #endif 3929 return; 3930 #endif 3931 3885 3932 // above 3886 3933 UInt uiAbovePartIdx = 0; … … 3895 3942 } 3896 3943 if ( pcCUAbove && !pcCUAbove->isIntra( uiAbovePartIdx ) 3897 #if MERL_VSP_C0152 3944 #if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092 3898 3945 CHECK_ADD_YET(pcCUAbove, uiAbovePartIdx, 1) 3899 3946 #endif … … 3943 3990 #endif 3944 3991 #if MERL_VSP_C0152 3992 #if LGE_VSP_INHERIT_D0092 3993 if (pcCUAbove->getVSPIndex(uiAbovePartIdx)==1) 3994 { 3995 iVSPIndexTrue[iCount] = 1; 3996 } 3997 #else 3945 3998 xInheritVspMode( pcCUAbove, uiAbovePartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo 3946 3999 #if QC_BVSP_CleanUP_D0191 … … 3949 4002 ) ; 3950 4003 #endif 4004 #endif 3951 4005 if ( mrgCandIdx == iCount ) 3952 4006 { … … 3958 4012 #endif 3959 4013 } 4014 4015 #if MERL_VSP_COMPENSATION_C0152 4016 //===== vsp 2 ===== 4017 #if LGE_VSP_INHERIT_D0092 4018 if ( !xAddVspMergeCand(2, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 4019 #else 4020 if( iCount < 4 + extraMergeCand ) 4021 if ( !xAddVspMergeCand(2, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 4022 #endif 4023 return; 4024 #endif 3960 4025 3961 4026 // above right … … 3971 4036 } 3972 4037 if ( pcCUAboveRight && !pcCUAboveRight->isIntra( uiAboveRightPartIdx ) 3973 #if MERL_VSP_C0152 4038 #if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092 3974 4039 CHECK_ADD_YET(pcCUAboveRight, uiAboveRightPartIdx, 1) 3975 4040 #endif … … 3996 4061 #endif 3997 4062 #if MERL_VSP_C0152 4063 #if LGE_VSP_INHERIT_D0092 4064 if (pcCUAboveRight->getVSPIndex(uiAboveRightPartIdx)==1) 4065 { 4066 iVSPIndexTrue[iCount] = 1; 4067 } 4068 #else 3998 4069 xInheritVspMode( pcCUAboveRight, uiAboveRightPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo 3999 4070 #if QC_BVSP_CleanUP_D0191 … … 4001 4072 #endif 4002 4073 ) ; 4074 #endif 4003 4075 #endif 4004 4076 if ( mrgCandIdx == iCount ) … … 4058 4130 #endif // H3D_IVMP 4059 4131 4132 #if MERL_VSP_COMPENSATION_C0152 4133 //===== vsp 3 ===== 4134 #if LGE_VSP_INHERIT_D0092 4135 if ( !xAddVspMergeCand(3, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 4136 #else 4137 if( iCount < 4 + extraMergeCand ) 4138 if ( !xAddVspMergeCand(3, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 4139 #endif 4140 return; 4141 #endif 4142 4143 #if MERL_VSP_C0152 4144 #if VSP_MERGE_POS < 4 4145 #if H3D_IVMP 4146 if( iCount < 4 + extraMergeCand ) 4147 #else 4148 if( iCount < 4 ) 4149 #endif 4150 { 4151 #endif 4152 #endif 4060 4153 4061 4154 //left bottom … … 4071 4164 } 4072 4165 if ( pcCULeftBottom && !pcCULeftBottom->isIntra( uiLeftBottomPartIdx ) 4073 #if MERL_VSP_C0152 4166 #if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092 4074 4167 CHECK_ADD_YET(pcCULeftBottom, uiLeftBottomPartIdx, 1) 4075 4168 #endif … … 4096 4189 #endif 4097 4190 #if MERL_VSP_C0152 4191 #if LGE_VSP_INHERIT_D0092 4192 if (pcCULeftBottom->getVSPIndex(uiLeftBottomPartIdx)==1) 4193 { 4194 iVSPIndexTrue[iCount] = 1; 4195 } 4196 #else 4098 4197 xInheritVspMode( pcCULeftBottom, uiLeftBottomPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo 4099 4198 #if QC_BVSP_CleanUP_D0191 … … 4102 4201 ) ; 4103 4202 #endif 4203 #endif 4104 4204 if ( mrgCandIdx == iCount ) 4105 4205 { … … 4108 4208 iCount ++; 4109 4209 } 4110 4111 4210 4211 #if MERL_VSP_C0152 4212 #if VSP_MERGE_POS < 4 4213 } 4214 #endif 4215 #endif 4216 4217 #if MERL_VSP_COMPENSATION_C0152 4218 //===== vsp 4 ===== 4219 if( iCount < 4 + extraMergeCand ) 4220 #if LGE_VSP_INHERIT_D0092 4221 if ( !xAddVspMergeCand(4, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 4222 #else 4223 if ( !xAddVspMergeCand(4, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 4224 #endif 4225 return; 4226 #endif 4227 4112 4228 // above left 4113 4229 #if H3D_IVMP … … 4128 4244 } 4129 4245 if( pcCUAboveLeft && !pcCUAboveLeft->isIntra( uiAboveLeftPartIdx ) 4130 #if MERL_VSP_C0152 4246 #if MERL_VSP_C0152 && !LGE_VSP_INHERIT_D0092 4131 4247 CHECK_ADD_YET(pcCUAboveLeft, uiAboveLeftPartIdx, 1) 4132 4248 #endif … … 4155 4271 #endif 4156 4272 #if MERL_VSP_C0152 4273 #if LGE_VSP_INHERIT_D0092 4274 if (pcCUAboveLeft->getVSPIndex(uiAboveLeftPartIdx)==1) 4275 { 4276 iVSPIndexTrue[iCount] = 1; 4277 } 4278 #else 4157 4279 xInheritVspMode( pcCUAboveLeft, uiAboveLeftPartIdx, bVspMvZeroDone, iCount, iVSPIndexTrue, pcMvFieldNeighbours, &cDisInfo 4158 4280 #if QC_BVSP_CleanUP_D0191 … … 4161 4283 ) ; 4162 4284 #endif 4285 #endif 4163 4286 if ( mrgCandIdx == iCount ) 4164 4287 { … … 4172 4295 //===== vsp 5 ===== 4173 4296 if( iCount < 4 + extraMergeCand ) 4297 #if LGE_VSP_INHERIT_D0092 4298 if ( !xAddVspMergeCand(5, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 4299 #else 4174 4300 if ( !xAddVspMergeCand(5, 1, bVspMvZeroDone, uiDepth, abCandIsInter, iCount, puhInterDirNeighbours, pcMvFieldNeighbours, iVSPIndexTrue, mrgCandIdx, &cDisInfo) ) 4301 #endif 4175 4302 return; 4176 4303 #endif … … 4362 4489 #if MERL_VSP_C0152 4363 4490 Bool bValid = true; 4491 #if LGE_VSP_INHERIT_D0092 4492 if (iVSPIndexTrue[i]==1 || iVSPIndexTrue[j]==1) // NOT_VALID 4493 #else 4364 4494 if (pcMvFieldNeighbours[i<<1].getRefIdx() < 0 || pcMvFieldNeighbours[(j<<1)+1].getRefIdx() < 0) // NOT_VALID 4495 #endif 4365 4496 bValid = false; 4366 4497 #endif … … 4997 5128 Int iPictureHeight = pcBaseViewDepthPicYuv->getHeight(); 4998 5129 #if !QC_BVSP_CleanUP_D0191 5130 #if LGE_ROUND_OFFSET_D0135 5131 Int depthPosX = Clip3(0, iPictureWidth - iBlkWidth, iBlkX + ((mv->getHor()+2)>>2)); 5132 Int depthPosY = Clip3(0, iPictureHeight- iBlkHeight, iBlkY + ((mv->getVer()+2)>>2)); 5133 #else 4999 5134 Int depthPosX = Clip3(0, iPictureWidth - iBlkWidth, iBlkX + (mv->getHor()>>2)); 5000 5135 Int depthPosY = Clip3(0, iPictureHeight- iBlkHeight, iBlkY + (mv->getVer()>>2)); 5136 #endif 5001 5137 5002 5138 Pel *pDepthPel = pcBaseViewDepthPicYuv->getLumaAddr() + depthPosX + depthPosY * depStride; … … 5006 5142 if ( bSimpleDvpRefine ) 5007 5143 { 5144 #if LGE_ROUND_OFFSET_D0135 5145 Int depthStartPosX = Clip3(0, iPictureWidth - iBlkWidth, iBlkX + ((mv->getHor()+2)>>2)); 5146 Int depthStartPosY = Clip3(0, iPictureHeight- iBlkHeight, iBlkY + ((mv->getVer()+2)>>2)); 5147 Int depthEndPosX = Clip3(0, iPictureWidth - 1, iBlkX + iBlkWidth - 1 + ((mv->getHor()+2)>>2)); 5148 Int depthEndPosY = Clip3(0, iPictureHeight - 1, iBlkY + iBlkHeight - 1 + ((mv->getVer()+2)>>2)); 5149 #else 5008 5150 Int depthStartPosX = Clip3(0, iPictureWidth - iBlkWidth, iBlkX + (mv->getHor()>>2)); 5009 5151 Int depthStartPosY = Clip3(0, iPictureHeight- iBlkHeight, iBlkY + (mv->getVer()>>2)); 5010 5152 Int depthEndPosX = Clip3(0, iPictureWidth - 1, iBlkX + iBlkWidth - 1 + (mv->getHor()>>2)); 5011 5153 Int depthEndPosY = Clip3(0, iPictureHeight - 1, iBlkY + iBlkHeight - 1 + (mv->getVer()>>2)); 5154 #endif 5012 5155 Int iCenterX = (depthStartPosX + depthEndPosX) >> 1; 5013 5156 Int iCenterY = (depthStartPosY + depthEndPosY) >> 1; -
branches/HTM-6.2-dev1-LG/source/Lib/TLibCommon/TComDataCU.h
r355 r408 275 275 Bool xAddMVPCandOrder ( AMVPInfo* pInfo, RefPicList eRefPicList, Int iRefIdx, UInt uiPartUnitIdx, MVP_DIR eDir ); 276 276 #if MERL_VSP_C0152 277 #if LGE_VSP_INHERIT_D0092 278 inline Bool xAddVspMergeCand ( UChar ucVspMergePos, UInt uiDepth, Bool* abCandIsInter, Int& iCount, 279 UChar* puhInterDirNeighbours, TComMvField* pcMvFieldNeighbours, Int* iVSPIndexTrue, Int mrgCandIdx, DisInfo* pDisInfo ); 280 #else 277 281 inline Bool xAddVspMergeCand ( UChar ucVspMergePos, Int vspIdx, Bool* bVspMvZeroDone, UInt uiDepth, Bool* abCandIsInter, Int& iCount, 278 282 UChar* puhInterDirNeighbours, TComMvField* pcMvFieldNeighbours, Int* iVSPIndexTrue, Int mrgCandIdx, DisInfo* pDisInfo ); 279 inline Void xInheritVspMode ( TComDataCU* pcCURef, UInt uiIdx, Bool* bVspMvZeroDone, Int iCount, Int* iVSPIndexTrue, TComMvField* pcMvFieldNeighbours, DisInfo* pDInfo, 283 #endif 284 inline Void xInheritVspMode ( TComDataCU* pcCURef, UInt uiIdx, Bool* bVspMvZeroDone, Int iCount, Int* iVSPIndexTrue, TComMvField* pcMvFieldNeighbours, DisInfo* pDInfo 280 285 #if QC_BVSP_CleanUP_D0191 281 UChar *puhInterDirNeighbours286 ,UChar *puhInterDirNeighbours 282 287 #endif 283 288 ) ; -
branches/HTM-6.2-dev1-LG/source/Lib/TLibCommon/TComPrediction.cpp
r355 r408 1309 1309 Int dstStride = dstPic->getStride(); 1310 1310 Int depStride = pPicBaseDepth->getStride(); 1311 #if LGE_ROUND_OFFSET_D0135 1312 Int depthPosX = Clip3(0, widthLuma - size_x, (posX/nTxtPerDepthX) + ((mv->getHor()+2)>>2)); 1313 Int depthPosY = Clip3(0, heightLuma- size_y, (posY/nTxtPerDepthY) + ((mv->getVer()+2)>>2)); 1314 #else 1311 1315 Int depthPosX = Clip3(0, widthLuma - size_x, (posX/nTxtPerDepthX) + (mv->getHor()>>2)); 1312 1316 Int depthPosY = Clip3(0, heightLuma- size_y, (posY/nTxtPerDepthY) + (mv->getVer()>>2)); 1317 #endif 1313 1318 Pel *ref = refPic->getLumaAddr() + posX + posY * refStride; 1314 1319 Pel *dst = dstPic->getLumaAddr(partAddr); … … 1460 1465 nTxtPerDepthX = widthChroma / widthDepth; 1461 1466 nDepthPerTxtX = 1; 1467 #if LGE_ROUND_OFFSET_D0135 1468 depthPosX = posX / nTxtPerDepthX + ((mv->getHor()+2)>>2); //mv denotes the disparity for VSP 1469 #else 1462 1470 depthPosX = posX / nTxtPerDepthX + (mv->getHor()>>2); //mv denotes the disparity for VSP 1471 #endif 1463 1472 } 1464 1473 else … … 1466 1475 nTxtPerDepthX = 1; 1467 1476 nDepthPerTxtX = widthDepth / widthChroma; 1477 #if LGE_ROUND_OFFSET_D0135 1478 depthPosX = posX * nDepthPerTxtX + ((mv->getHor()+2)>>2); //mv denotes the disparity for VSP 1479 #else 1468 1480 depthPosX = posX * nDepthPerTxtX + (mv->getHor()>>2); //mv denotes the disparity for VSP 1481 #endif 1469 1482 } 1470 1483 depthPosX = Clip3(0, widthDepth - (size_x<<1), depthPosX); … … 1473 1486 nTxtPerDepthY = heightChroma / heightDepth; 1474 1487 nDepthPerTxtY = 1; 1488 #if LGE_ROUND_OFFSET_D0135 1489 depthPosY = posY / nTxtPerDepthY + ((mv->getVer()+2)>>2); //mv denotes the disparity for VSP 1490 #else 1475 1491 depthPosY = posY / nTxtPerDepthY + (mv->getVer()>>2); //mv denotes the disparity for VSP 1492 #endif 1476 1493 } 1477 1494 else … … 1479 1496 nTxtPerDepthY = 1; 1480 1497 nDepthPerTxtY = heightDepth / heightChroma; 1498 #if LGE_ROUND_OFFSET_D0135 1499 depthPosY = posY * nDepthPerTxtY + ((mv->getVer()+2)>>2); //mv denotes the disparity for VSP 1500 #else 1481 1501 depthPosY = posY * nDepthPerTxtY + (mv->getVer()>>2); //mv denotes the disparity for VSP 1502 #endif 1482 1503 } 1483 1504 depthPosY = Clip3(0, heightDepth - (size_y<<1), depthPosY); … … 2078 2099 iCUPelX = pcCU->getCUPelX() + g_auiRasterToPelX[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]]; 2079 2100 iCUPelY = pcCU->getCUPelY() + g_auiRasterToPelY[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]]; 2101 #if LGE_ROUND_OFFSET_D0135 2102 iRefX = iCUPelX + ((pMv->getHor()+2) >> 2); 2103 iRefY = iCUPelY + ((pMv->getVer()+2) >> 2); 2104 #else 2080 2105 iRefX = iCUPelX + (pMv->getHor() >> 2); 2081 2106 iRefY = iCUPelY + (pMv->getVer() >> 2); 2107 #endif 2082 2108 uiWidth = pcCU->getWidth(0); 2083 2109 uiHeight = pcCU->getHeight(0); … … 2091 2117 if(pcCU->getPUAbove(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelY > 0 && iRefY > 0) 2092 2118 { 2119 #if LGE_ROUND_OFFSET_D0135 2120 iRefOffset = ( (pMv->getHor()+2) >> 2 ) + ( (pMv->getVer()+2) >> 2 ) * iRefStride - iRefStride; 2121 #else 2093 2122 iRefOffset = ( pMv->getHor() >> 2 ) + ( pMv->getVer() >> 2 ) * iRefStride - iRefStride; 2123 #endif 2094 2124 pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset; 2095 2125 pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride; … … 2108 2138 if(pcCU->getPULeft(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelX > 0 && iRefX > 0) 2109 2139 { 2140 #if LGE_ROUND_OFFSET_D0135 2141 iRefOffset = ( (pMv->getHor()+2) >> 2 ) + ( (pMv->getVer()+2) >> 2 ) * iRefStride - 1; 2142 #else 2110 2143 iRefOffset = ( pMv->getHor() >> 2 ) + ( pMv->getVer() >> 2 ) * iRefStride - 1; 2144 #endif 2111 2145 pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset; 2112 2146 pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1; … … 2226 2260 iCUPelX = pcCU->getCUPelX() + g_auiRasterToPelX[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]]; 2227 2261 iCUPelY = pcCU->getCUPelY() + g_auiRasterToPelY[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]]; 2262 #if LGE_ROUND_OFFSET_D0135 2263 iRefX = iCUPelX + ((pMv->getHor()+2) >> 2); 2264 iRefY = iCUPelY + ((pMv->getVer()+2) >> 2); 2265 #else 2228 2266 iRefX = iCUPelX + (pMv->getHor() >> 2); 2229 2267 iRefY = iCUPelY + (pMv->getVer() >> 2); 2268 #endif 2230 2269 uiWidth = pcCU->getWidth(0) >> 1; 2231 2270 uiHeight = pcCU->getHeight(0) >> 1; … … 2239 2278 if(pcCU->getPUAbove(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelY > 0 && iRefY > 0) 2240 2279 { 2280 #if LGE_ROUND_OFFSET_D0135 2281 iRefOffset = ( (pMv->getHor()+4) >> 3 ) + ( (pMv->getVer()+4) >> 3 ) * iRefStride - iRefStride; 2282 #else 2241 2283 iRefOffset = ( pMv->getHor() >> 3 ) + ( pMv->getVer() >> 3 ) * iRefStride - iRefStride; 2284 #endif 2242 2285 if (iChromaId == 0) // Cb 2243 2286 { … … 2264 2307 if(pcCU->getPULeft(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelX > 0 && iRefX > 0) 2265 2308 { 2309 #if LGE_ROUND_OFFSET_D0135 2310 iRefOffset = ( (pMv->getHor()+4) >> 3 ) + ( (pMv->getVer()+4) >> 3 ) * iRefStride - 1; 2311 #else 2266 2312 iRefOffset = ( pMv->getHor() >> 3 ) + ( pMv->getVer() >> 3 ) * iRefStride - 1; 2313 #endif 2267 2314 if (iChromaId == 0) // Cb 2268 2315 { -
branches/HTM-6.2-dev1-LG/source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp
r296 r408 62 62 TComSampleAdaptiveOffset::TComSampleAdaptiveOffset() 63 63 { 64 #if !LGE_SAO_MIGRATION_D0091 64 65 m_pcPic = NULL; 66 #endif 65 67 m_iOffsetBo = NULL; 66 68 m_pClipTable = NULL; … … 71 73 m_iUpBufft = NULL; 72 74 ipSwap = NULL; 75 #if !LGE_SAO_MIGRATION_D0091 73 76 m_pcYuvTmp = NULL; 77 #endif 74 78 75 79 m_pTmpU1 = NULL; … … 85 89 } 86 90 91 #if !LGE_SAO_MIGRATION_D0091 87 92 const Int TComSampleAdaptiveOffset::m_aiNumPartsInRow[5] = 88 93 { … … 102 107 256 //level 4 103 108 }; 109 #endif 104 110 105 111 const Int TComSampleAdaptiveOffset::m_aiNumCulPartsLevel[5] = … … 124 130 0 125 131 }; 126 132 #if !LGE_SAO_MIGRATION_D0091 127 133 const UInt TComSampleAdaptiveOffset::m_iWeightSao[MAX_NUM_SAO_TYPE] = 128 134 { … … 146 152 6 147 153 }; 154 #endif 148 155 149 156 Int TComSampleAdaptiveOffset::m_iNumClass[MAX_NUM_SAO_TYPE] = … … 187 194 return idx; 188 195 } 196 #if !LGE_SAO_MIGRATION_D0091 189 197 /** convert quadtree Idx to Level, Row, and Col 190 198 * \param idx, *level, *row, *col … … 223 231 } 224 232 } 233 #endif 225 234 /** create SampleAdaptiveOffset memory. 226 235 * \param … … 317 326 } 318 327 319 328 #if LGE_SAO_MIGRATION_D0091 329 if (m_iUpBuff1) 330 { 331 m_iUpBuff1--; 332 delete [] m_iUpBuff1; m_iUpBuff1 = NULL; 333 } 334 if (m_iUpBuff2) 335 { 336 m_iUpBuff2--; 337 delete [] m_iUpBuff2; m_iUpBuff2 = NULL; 338 } 339 if (m_iUpBufft) 340 { 341 m_iUpBufft--; 342 delete [] m_iUpBufft; m_iUpBufft = NULL; 343 } 344 #else 320 345 m_iUpBuff1--; 321 346 m_iUpBuff2--; … … 334 359 delete [] m_iUpBufft; m_iUpBufft = NULL; 335 360 } 361 #endif 336 362 if (m_pTmpL1) 337 363 { … … 368 394 initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1, 0, m_iNumCuInHeight-1,1); 369 395 initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1, 0, m_iNumCuInHeight-1,2); 396 #if !LGE_SAO_MIGRATION_D0091 370 397 for(Int j=0;j<MAX_NUM_SAO_TYPE;j++) 371 398 { 372 399 pcSaoParam->iNumClass[j] = m_iNumClass[j]; 373 400 } 401 #endif 374 402 pcSaoParam->numCuInWidth = m_iNumCuInWidth; 375 403 pcSaoParam->numCuInHeight = m_iNumCuInHeight; … … 405 433 pSaoPart->iLength = 0; 406 434 435 #if LGE_SAO_MIGRATION_D0091 436 pSaoPart->subTypeIdx = 0; 437 #else 407 438 pSaoPart->bandPosition = 0; 439 #endif 408 440 409 441 for (j=0;j<MAX_NUM_SAO_OFFSETS;j++) … … 514 546 for(Int c=0; c<iNumComponet; c++) 515 547 { 548 #if LGE_SAO_MIGRATION_D0091 549 if (c<2) 550 { 551 pcSaoParam->bSaoFlag[c] = 0; 552 } 553 #else 516 554 pcSaoParam->bSaoFlag[c] = 0; 555 #endif 517 556 for(Int i=0; i< m_aiNumCulPartsLevel[m_uiMaxSplitLevel]; i++) 518 557 { … … 524 563 pcSaoParam->psSaoPart[c][i].iMinDist = MAX_INT; 525 564 pcSaoParam->psSaoPart[c][i].iMinRate = MAX_INT; 565 #if LGE_SAO_MIGRATION_D0091 566 pcSaoParam->psSaoPart[c][i].subTypeIdx = 0; 567 #else 526 568 pcSaoParam->psSaoPart[c][i].bandPosition = 0; 569 #endif 527 570 for (Int j=0;j<MAX_NUM_SAO_OFFSETS;j++) 528 571 { … … 557 600 m_pcPic = pcPic; 558 601 m_uiNumSlicesInPic = numSlicesInPic; 602 #if LGE_SAO_MIGRATION_D0091 603 m_iSGDepth = 0; 604 #else 559 605 m_iSGDepth = pcPic->getSliceGranularityForNDBFilter(); 606 #endif 560 607 m_bUseNIF = ( pcPic->getIndependentSliceBoundaryForNDBFilter() || pcPic->getIndependentTileBoundaryForNDBFilter() ); 561 608 if(m_bUseNIF) … … 958 1005 uiEdgeType = iSignDown + m_iUpBuff1[x] + 2; 959 1006 m_iUpBuff1[x]= -iSignDown; 960 961 1007 pRec[x] = m_pClipTable[pRec[x] + m_iOffsetEo[uiEdgeType]]; 962 1008 } … … 1065 1111 Void TComSampleAdaptiveOffset::SAOProcess(TComPic* pcPic, SAOParam* pcSaoParam) 1066 1112 { 1113 #if LGE_SAO_MIGRATION_D0091 1114 if (pcSaoParam->bSaoFlag[0] || pcSaoParam->bSaoFlag[1]) 1115 #else 1067 1116 if (pcSaoParam->bSaoFlag[0]) 1117 #endif 1068 1118 { 1069 1119 #if FULL_NBIT … … 1077 1127 m_pcPic->getPicYuvRec()->copyToPic(m_pcYuvTmp); 1078 1128 } 1079 1129 #if LGE_SAO_MIGRATION_D0091 1130 if (m_saoLcuBasedOptimization) 1131 #else 1080 1132 if (m_saoInterleavingFlag) 1133 #endif 1081 1134 { 1082 1135 pcSaoParam->oneUnitFlag[0] = 0; … … 1085 1138 } 1086 1139 Int iY = 0; 1140 #if LGE_SAO_MIGRATION_D0091 1141 if (pcSaoParam->bSaoFlag[0]) 1142 { 1143 processSaoUnitAll( pcSaoParam->saoLcuParam[iY], pcSaoParam->oneUnitFlag[iY], iY); 1144 } 1145 if(pcSaoParam->bSaoFlag[1]) 1146 { 1147 processSaoUnitAll( pcSaoParam->saoLcuParam[1], pcSaoParam->oneUnitFlag[1], 1);//Cb 1148 processSaoUnitAll( pcSaoParam->saoLcuParam[2], pcSaoParam->oneUnitFlag[2], 2);//Cr 1149 } 1150 #else 1087 1151 processSaoUnitAll( pcSaoParam->saoLcuParam[iY], pcSaoParam->oneUnitFlag[iY], iY); 1088 1152 … … 1097 1161 processSaoUnitAll( pcSaoParam->saoLcuParam[iCr], pcSaoParam->oneUnitFlag[iCr], iCr); 1098 1162 } 1099 1100 1163 #endif 1101 1164 m_pcPic = NULL; 1102 1165 } … … 1154 1217 Int typeIdx; 1155 1218 1219 #if LGE_SAO_MIGRATION_D0091 1220 Int offset[LUMA_GROUP_NUM+1]; 1221 #else 1156 1222 static Int offset[LUMA_GROUP_NUM+1]; 1223 #endif 1157 1224 Int idxX; 1158 1225 Int idxY; … … 1164 1231 Int isChroma = (yCbCr == 0) ? 0:1; 1165 1232 Bool mergeLeftFlag; 1166 1167 1233 #if LGE_SAO_MIGRATION_D0091 1234 offset[0] = 0; 1235 #endif 1168 1236 for (idxY = 0; idxY< frameHeightInCU; idxY++) 1169 1237 { … … 1201 1269 { 1202 1270 addr = idxY * frameWidthInCU + idxX; 1203 1204 1271 if (oneUnitFlag) 1205 1272 { … … 1225 1292 for (i=0; i<saoLcuParam[addr].length; i++) 1226 1293 { 1294 #if LGE_SAO_MIGRATION_D0091 1295 offset[ (saoLcuParam[addr].subTypeIdx +i)%SAO_MAX_BO_CLASSES +1] = saoLcuParam[addr].offset[i] << m_uiSaoBitIncrease; 1296 #else 1227 1297 offset[ (saoLcuParam[addr].bandPosition +i)%SAO_MAX_BO_CLASSES +1] = saoLcuParam[addr].offset[i] << m_uiSaoBitIncrease; 1298 #endif 1228 1299 } 1229 1300 … … 1304 1375 saoLcuParam[i].offset[j] = 0; 1305 1376 } 1377 #if LGE_SAO_MIGRATION_D0091 1378 saoLcuParam[i].subTypeIdx = 0; 1379 #else 1306 1380 saoLcuParam[i].bandPosition = 0; 1381 #endif 1307 1382 } 1308 1383 } … … 1353 1428 saoLcuParam[addr].partIdxTmp = (Int)partIdx; 1354 1429 saoLcuParam[addr].typeIdx = saoQTPart[partIdx].iBestType; 1430 #if LGE_SAO_MIGRATION_D0091 1431 saoLcuParam[addr].subTypeIdx = saoQTPart[partIdx].subTypeIdx; 1432 #else 1355 1433 saoLcuParam[addr].bandPosition = saoQTPart[partIdx].bandPosition; 1434 #endif 1356 1435 if (saoLcuParam[addr].typeIdx!=-1) 1357 1436 { … … 1365 1444 { 1366 1445 saoLcuParam[addr].length = 0; 1446 #if LGE_SAO_MIGRATION_D0091 1447 saoLcuParam[addr].subTypeIdx = saoQTPart[partIdx].subTypeIdx; 1448 #else 1367 1449 saoLcuParam[addr].bandPosition = saoQTPart[partIdx].bandPosition; 1450 #endif 1368 1451 for (j=0;j<MAX_NUM_SAO_OFFSETS;j++) 1369 1452 { … … 1375 1458 } 1376 1459 1377 1378 1460 #if LGE_SAO_MIGRATION_D0091 1461 Void TComSampleAdaptiveOffset::resetSaoUnit(SaoLcuParam* saoUnit) 1462 { 1463 saoUnit->partIdx = 0; 1464 saoUnit->partIdxTmp = 0; 1465 saoUnit->mergeLeftFlag = 0; 1466 saoUnit->mergeUpFlag = 0; 1467 saoUnit->typeIdx = -1; 1468 saoUnit->length = 0; 1469 saoUnit->subTypeIdx = 0; 1470 1471 for (Int i=0;i<4;i++) 1472 { 1473 saoUnit->offset[i] = 0; 1474 } 1475 } 1476 1477 Void TComSampleAdaptiveOffset::copySaoUnit(SaoLcuParam* saoUnitDst, SaoLcuParam* saoUnitSrc ) 1478 { 1479 saoUnitDst->mergeLeftFlag = saoUnitSrc->mergeLeftFlag; 1480 saoUnitDst->mergeUpFlag = saoUnitSrc->mergeUpFlag; 1481 saoUnitDst->typeIdx = saoUnitSrc->typeIdx; 1482 saoUnitDst->length = saoUnitSrc->length; 1483 1484 saoUnitDst->subTypeIdx = saoUnitSrc->subTypeIdx; 1485 for (Int i=0;i<4;i++) 1486 { 1487 saoUnitDst->offset[i] = saoUnitSrc->offset[i]; 1488 } 1489 } 1490 1491 /** PCM LF disable process. 1492 * \param pcPic picture (TComPic) pointer 1493 * \returns Void 1494 * 1495 * \note Replace filtered sample values of PCM mode blocks with the transmitted and reconstructed ones. 1496 */ 1497 Void TComSampleAdaptiveOffset::PCMLFDisableProcess (TComPic* pcPic) 1498 { 1499 xPCMRestoration(pcPic); 1500 } 1501 1502 /** Picture-level PCM restoration. 1503 * \param pcPic picture (TComPic) pointer 1504 * \returns Void 1505 */ 1506 Void TComSampleAdaptiveOffset::xPCMRestoration(TComPic* pcPic) 1507 { 1508 Bool bPCMFilter = (pcPic->getSlice(0)->getSPS()->getUsePCM() && pcPic->getSlice(0)->getSPS()->getPCMFilterDisableFlag())? true : false; 1509 #if LOSSLESS_CODING 1510 if(bPCMFilter || pcPic->getSlice(0)->getSPS()->getUseLossless()) 1511 #else 1512 if(bPCMFilter) 1513 #endif 1514 { 1515 for( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame() ; uiCUAddr++ ) 1516 { 1517 TComDataCU* pcCU = pcPic->getCU(uiCUAddr); 1518 xPCMCURestoration(pcCU, 0, 0); 1519 } 1520 } 1521 } 1522 1523 /** PCM CU restoration. 1524 * \param pcCU pointer to current CU 1525 * \param uiAbsPartIdx part index 1526 * \param uiDepth CU depth 1527 * \returns Void 1528 */ 1529 Void TComSampleAdaptiveOffset::xPCMCURestoration ( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth ) 1530 { 1531 TComPic* pcPic = pcCU->getPic(); 1532 UInt uiCurNumParts = pcPic->getNumPartInCU() >> (uiDepth<<1); 1533 UInt uiQNumParts = uiCurNumParts>>2; 1534 1535 // go to sub-CU 1536 if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth ) 1537 { 1538 for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts ) 1539 { 1540 UInt uiLPelX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ]; 1541 UInt uiTPelY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ]; 1542 if( ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) ) 1543 xPCMCURestoration( pcCU, uiAbsZorderIdx, uiDepth+1 ); 1544 } 1545 return; 1546 } 1547 1548 // restore PCM samples 1549 if ((pcCU->getIPCMFlag(uiAbsZorderIdx)&& pcPic->getSlice(0)->getSPS()->getPCMFilterDisableFlag()) || pcCU->isLosslessCoded( uiAbsZorderIdx)) 1550 { 1551 xPCMSampleRestoration (pcCU, uiAbsZorderIdx, uiDepth, TEXT_LUMA ); 1552 xPCMSampleRestoration (pcCU, uiAbsZorderIdx, uiDepth, TEXT_CHROMA_U); 1553 xPCMSampleRestoration (pcCU, uiAbsZorderIdx, uiDepth, TEXT_CHROMA_V); 1554 } 1555 } 1556 1557 /** PCM sample restoration. 1558 * \param pcCU pointer to current CU 1559 * \param uiAbsPartIdx part index 1560 * \param uiDepth CU depth 1561 * \param ttText texture component type 1562 * \returns Void 1563 */ 1564 Void TComSampleAdaptiveOffset::xPCMSampleRestoration (TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, TextType ttText) 1565 { 1566 TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec(); 1567 Pel* piSrc; 1568 Pel* piPcm; 1569 UInt uiStride; 1570 UInt uiWidth; 1571 UInt uiHeight; 1572 UInt uiPcmLeftShiftBit; 1573 UInt uiX, uiY; 1574 UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight(); 1575 UInt uiLumaOffset = uiMinCoeffSize*uiAbsZorderIdx; 1576 UInt uiChromaOffset = uiLumaOffset>>2; 1577 1578 if( ttText == TEXT_LUMA ) 1579 { 1580 piSrc = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx); 1581 piPcm = pcCU->getPCMSampleY() + uiLumaOffset; 1582 uiStride = pcPicYuvRec->getStride(); 1583 uiWidth = (g_uiMaxCUWidth >> uiDepth); 1584 uiHeight = (g_uiMaxCUHeight >> uiDepth); 1585 if ( pcCU->isLosslessCoded(uiAbsZorderIdx) ) 1586 { 1587 uiPcmLeftShiftBit = 0; 1588 } 1589 else 1590 { 1591 uiPcmLeftShiftBit = g_uiBitDepth + g_uiBitIncrement - pcCU->getSlice()->getSPS()->getPCMBitDepthLuma(); 1592 } 1593 } 1594 else 1595 { 1596 if( ttText == TEXT_CHROMA_U ) 1597 { 1598 piSrc = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx ); 1599 piPcm = pcCU->getPCMSampleCb() + uiChromaOffset; 1600 } 1601 else 1602 { 1603 piSrc = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx ); 1604 piPcm = pcCU->getPCMSampleCr() + uiChromaOffset; 1605 } 1606 1607 uiStride = pcPicYuvRec->getCStride(); 1608 uiWidth = ((g_uiMaxCUWidth >> uiDepth)/2); 1609 uiHeight = ((g_uiMaxCUWidth >> uiDepth)/2); 1610 if ( pcCU->isLosslessCoded(uiAbsZorderIdx) ) 1611 { 1612 uiPcmLeftShiftBit = 0; 1613 } 1614 else 1615 { 1616 uiPcmLeftShiftBit = g_uiBitDepth + g_uiBitIncrement - pcCU->getSlice()->getSPS()->getPCMBitDepthChroma(); 1617 } 1618 } 1619 1620 for( uiY = 0; uiY < uiHeight; uiY++ ) 1621 { 1622 for( uiX = 0; uiX < uiWidth; uiX++ ) 1623 { 1624 piSrc[uiX] = (piPcm[uiX] << uiPcmLeftShiftBit); 1625 } 1626 piPcm += uiWidth; 1627 piSrc += uiStride; 1628 } 1629 } 1630 #endif 1379 1631 //! \} -
branches/HTM-6.2-dev1-LG/source/Lib/TLibCommon/TComSampleAdaptiveOffset.h
r296 r408 65 65 66 66 static UInt m_uiMaxDepth; 67 #if !LGE_SAO_MIGRATION_D0091 67 68 static const Int m_aiNumPartsInRow[5]; 68 69 static const Int m_aiNumPartsLevel[5]; 70 #endif 69 71 static const Int m_aiNumCulPartsLevel[5]; 70 72 static const UInt m_auiEoTable[9]; 73 #if !LGE_SAO_MIGRATION_D0091 71 74 static const UInt m_auiEoTable2D[9]; 72 75 static const UInt m_iWeightSao[MAX_NUM_SAO_TYPE]; 76 #endif 73 77 Int *m_iOffsetBo; 74 78 Int m_iOffsetEo[LUMA_GROUP_NUM]; … … 107 111 Int* m_iLcuPartIdx; 108 112 Int m_maxNumOffsetsPerPic; 113 #if LGE_SAO_MIGRATION_D0091 114 Bool m_saoLcuBoundary; 115 Bool m_saoLcuBasedOptimization; 116 117 Void xPCMRestoration (TComPic* pcPic); 118 Void xPCMCURestoration (TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth); 119 Void xPCMSampleRestoration (TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, TextType ttText); 120 #else 109 121 Bool m_saoInterleavingFlag; 122 #endif 110 123 public: 111 124 TComSampleAdaptiveOffset (); … … 116 129 117 130 Int convertLevelRowCol2Idx(int level, int row, int col); 131 #if !LGE_SAO_MIGRATION_D0091 118 132 void convertIdx2LevelRowCol(int idx, int *level, int *row, int *col); 133 #endif 119 134 120 135 Void initSAOParam (SAOParam *pcSaoParam, Int iPartLevel, Int iPartRow, Int iPartCol, Int iParentPartIdx, Int StartCUX, Int EndCUX, Int StartCUY, Int EndCUY, Int iYCbCr); 121 136 Void allocSaoParam (SAOParam* pcSaoParam); 122 137 Void resetSAOParam (SAOParam *pcSaoParam); 138 #if LGE_SAO_MIGRATION_D0091 139 static Void freeSaoParam (SAOParam *pcSaoParam); 140 #else 123 141 Void freeSaoParam (SAOParam *pcSaoParam); 142 #endif 143 124 144 125 145 Void SAOProcess(TComPic* pcPic, SAOParam* pcSaoParam); 126 146 Void processSaoCu(Int iAddr, Int iSaoType, Int iYCbCr); 147 #if !LGE_SAO_MIGRATION_D0091 127 148 Void processSaoOnePart(SAOQTPart *psQTPart, UInt uiPartIdx, Int iYCbCr); 128 149 Void processSaoQuadTree(SAOQTPart *psQTPart, UInt uiPartIdx, Int iYCbCr); 150 #endif 129 151 Pel* getPicYuvAddr(TComPicYuv* pcPicYuv, Int iYCbCr,Int iAddr = 0); 130 152 … … 138 160 Void convertOnePart2SaoUnit(SAOParam *saoParam, UInt partIdx, Int yCbCr); 139 161 Void processSaoUnitAll(SaoLcuParam* saoLcuParam, Bool oneUnitFlag, Int yCbCr); 162 #if LGE_SAO_MIGRATION_D0091 163 Void setSaoLcuBoundary (Bool bVal) {m_saoLcuBoundary = bVal;} 164 Bool getSaoLcuBoundary () {return m_saoLcuBoundary;} 165 Void setSaoLcuBasedOptimization (Bool bVal) {m_saoLcuBasedOptimization = bVal;} 166 Bool getSaoLcuBasedOptimization () {return m_saoLcuBasedOptimization;} 167 Void resetSaoUnit(SaoLcuParam* saoUnit); 168 Void copySaoUnit(SaoLcuParam* saoUnitDst, SaoLcuParam* saoUnitSrc ); 169 Void PCMLFDisableProcess ( TComPic* pcPic); ///< interface function for ALF process 170 #else 140 171 Void setSaoInterleavingFlag (Bool bVal) {m_saoInterleavingFlag = bVal;} 141 172 Bool getSaoInterleavingFlag () {return m_saoInterleavingFlag;} 173 #endif 142 174 }; 143 175 -
branches/HTM-6.2-dev1-LG/source/Lib/TLibCommon/TComSlice.cpp
r380 r408 821 821 822 822 m_saoEnabledFlag = pSrc->m_saoEnabledFlag; 823 #if LGE_SAO_MIGRATION_D0091 824 m_saoEnabledFlagChroma = pSrc->m_saoEnabledFlagChroma; 825 #else 823 826 m_saoInterleavingFlag = pSrc->m_saoInterleavingFlag; 824 827 m_saoEnabledFlagCb = pSrc->m_saoEnabledFlagCb; 825 828 m_saoEnabledFlagCr = pSrc->m_saoEnabledFlagCr; 829 #endif 826 830 #if CABAC_INIT_FLAG 827 831 m_cabacInitFlag = pSrc->m_cabacInitFlag; … … 2051 2055 m_scalingList = src.m_scalingList; 2052 2056 m_scalingListEnabled = src.m_scalingListEnabled; 2057 #if !LGE_SAO_MIGRATION_D0091 2053 2058 m_saoInterleavingFlag = src.m_saoInterleavingFlag; 2059 #endif 2054 2060 2055 2061 return *this; -
branches/HTM-6.2-dev1-LG/source/Lib/TLibCommon/TComSlice.h
r384 r408 964 964 Bool getScalingListEnabled () { return m_scalingListEnabled; } //!< get ScalingList enabled/disabled in APS 965 965 TComScalingList* getScalingList () { return m_scalingList; } //!< get ScalingList class pointer in APS 966 #if !LGE_SAO_MIGRATION_D0091 966 967 Bool getSaoInterleavingFlag() {return m_saoInterleavingFlag;} //!< get SAO interleaving flag in APS 967 968 Void setSaoInterleavingFlag(Bool bVal) {m_saoInterleavingFlag = bVal;} //!< set SAO interleaving flag in APS 969 #endif 968 970 969 971 private: … … 979 981 Bool m_scalingListEnabled; //!< ScalingList enabled/disabled in APS (true for enabled) 980 982 TComScalingList* m_scalingList; //!< ScalingList class pointer 983 #if !LGE_SAO_MIGRATION_D0091 981 984 Bool m_saoInterleavingFlag; //!< SAO interleaving flag 985 #endif 982 986 983 987 public: … … 1011 1015 bool m_alfEnabledFlag; 1012 1016 bool m_saoEnabledFlag; 1017 #if LGE_SAO_MIGRATION_D0091 1018 bool m_saoEnabledFlagChroma; ///< SAO Cb&Cr enabled flag 1019 #else 1013 1020 bool m_saoInterleavingFlag; ///< SAO interleaving flag 1014 1021 bool m_saoEnabledFlagCb; ///< SAO Cb enabled flag 1015 1022 bool m_saoEnabledFlagCr; ///< SAO Cr enabled flag 1023 #endif 1016 1024 Int m_iPPSId; ///< picture parameter set ID 1017 1025 Bool m_PicOutputFlag; ///< pic_output_flag … … 1198 1206 Void setSaoEnabledFlag(Bool s) {m_saoEnabledFlag =s; } 1199 1207 Bool getSaoEnabledFlag() { return m_saoEnabledFlag; } 1208 #if LGE_SAO_MIGRATION_D0091 1209 Void setSaoEnabledFlagChroma(Bool s) {m_saoEnabledFlagChroma =s; } //!< set SAO Cb&Cr enabled flag 1210 Bool getSaoEnabledFlagChroma() { return m_saoEnabledFlagChroma; } //!< get SAO Cb&Cr enabled flag 1211 #else 1200 1212 Void setSaoInterleavingFlag(Bool s) {m_saoInterleavingFlag =s; } //!< set SAO interleaving flag 1201 1213 Bool getSaoInterleavingFlag() { return m_saoInterleavingFlag; } //!< get SAO interleaving flag … … 1204 1216 Void setSaoEnabledFlagCr(Bool s) {m_saoEnabledFlagCr =s; } //!< set SAO Cr enabled flag 1205 1217 Bool getSaoEnabledFlagCr() { return m_saoEnabledFlagCr; } //!< get SAO Cr enabled flag 1218 #endif 1206 1219 Void setRPS ( TComReferencePictureSet *pcRPS ) { m_pcRPS = pcRPS; } 1207 1220 TComReferencePictureSet* getRPS () { return m_pcRPS; } -
branches/HTM-6.2-dev1-LG/source/Lib/TLibCommon/TypeDef.h
r384 r408 161 161 #define FIX_LGE_WP_FOR_3D_C0223 1 // JCT3V-C0223 Weighted Prediction Bug-fix for 3D-HEVC. Caution! There is still crush using WP with Residual Prediction. 162 162 #define FIX_APPENCTOP_T_ONLY 1 // For Texture-only coding 163 #define LGE_ROUND_OFFSET_D0135 1 // JCT3V-D0135 Rounding offset 164 #define LGE_SAO_MIGRATION_D0091 1 165 166 #if LGE_SAO_MIGRATION_D0091 167 #define SAO_SKIP_RIGHT 1 ///< H1101: disallow using unavailable pixel during RDO 168 #define SAO_ENCODING_CHOICE 1 ///< I0184: picture early termination 169 #if SAO_ENCODING_CHOICE 170 #define SAO_ENCODING_RATE 0.75 171 #define SAO_ENCODING_CHOICE_CHROMA 1 ///< J0044: picture early termination Luma and Chroma are handled separatenly 172 #if SAO_ENCODING_CHOICE_CHROMA 173 #define SAO_ENCODING_RATE_CHROMA 0.5 174 #define SAO_ENCODING_CHOICE_CHROMA_BF 1 /// K0156: Bug fix for SAO selection consistency 175 #endif 176 #endif 177 #endif 163 178 164 179 ///// ***** FCO ********* … … 186 201 187 202 #define MTK_D0156 1 203 #define LGE_VSP_INHERIT_D0092 1 188 204 /* 189 205 * Two macros are used to configure combinations of JCT3V-C0152 and JCT3V-C0131 … … 206 222 207 223 #define MERL_VSP_BLOCKSIZE_C0152 4 // JCT3V-C0152: VSP block size, supported values: 1, 2 and 4. 224 #if LGE_VSP_INHERIT_D0092 225 #define VSP_MERGE_POS 3 // JCT3V-C0152: fixed position of VSP candidate in merge list, supported values: 3. 226 #else 208 227 #define VSP_MERGE_POS 5 // JCT3V-C0152: fixed position of VSP candidate in merge list, supported values: 5. 228 #endif 209 229 //MTK_DVPREFINE_BVSP_BUG_FIX 1 210 230 … … 349 369 #define C2FLAG_NUMBER 1 // maximum number of largerThan2 flag coded in one chunk: 16 in HM5 350 370 371 #if !LGE_SAO_MIGRATION_D0091 351 372 #define REMOVE_SAO_LCU_ENC_CONSTRAINTS_1 0 ///< disable the encoder constraint that does not test SAO/BO mode for chroma in interleaved mode 352 373 #define REMOVE_SAO_LCU_ENC_CONSTRAINTS_2 0 ///< disable the encoder constraint that reduce the range of SAO/EO for chroma in interleaved mode 374 #endif 353 375 #define REMOVE_SAO_LCU_ENC_CONSTRAINTS_3 0 ///< disable the encoder constraint that conditionally disable SAO for chroma for entire slice in interleaved mode 354 376 #define COLLOCATED_REF_IDX 1 ///< H0442: signal collocated reference index … … 623 645 Int iBestType; 624 646 Int iLength; 647 #if LGE_SAO_MIGRATION_D0091 648 Int subTypeIdx ; ///< indicates EO class or BO band position 649 #else 625 650 Int bandPosition ; 651 #endif 626 652 Int iOffset[4]; 627 653 Int StartCUX; … … 653 679 Bool mergeLeftFlag; 654 680 Int typeIdx; 681 #if LGE_SAO_MIGRATION_D0091 682 Int subTypeIdx; 683 #else 655 684 Int bandPosition; 685 #endif 656 686 Int offset[4]; 687 #if !LGE_SAO_MIGRATION_D0091 657 688 Int runDiff; 658 689 Int run; 690 #endif 659 691 Int partIdx; 660 692 Int partIdxTmp; -
branches/HTM-6.2-dev1-LG/source/Lib/TLibDecoder/TDecCAVLC.cpp
r384 r408 265 265 xParseDblParam( aps ); 266 266 } 267 #if !LGE_SAO_MIGRATION_D0091 267 268 READ_FLAG(uiCode, "aps_sao_interleaving_flag"); aps->setSaoInterleavingFlag( (uiCode==1)?true:false ); 268 269 if(!aps->getSaoInterleavingFlag()) … … 275 276 } 276 277 } 278 #endif 277 279 READ_FLAG(uiCode, "aps_adaptive_loop_filter_flag"); aps->setAlfEnabled( (uiCode==1)?true:false ); 278 280 if(aps->getAlfEnabled()) … … 307 309 } 308 310 } 311 #if !LGE_SAO_MIGRATION_D0091 309 312 /** parse SAO parameters 310 313 * \param pSaoParam … … 532 535 } 533 536 } 534 537 #endif 535 538 536 539 Void TDecCavlc::xParseAlfParam(AlfParamSet* pAlfParamSet, Bool bSentInAPS, Int firstLCUAddr, Bool acrossSlice, Int numLCUInWidth, Int numLCUInHeight) … … 1866 1869 if (sps->getUseSAO()) 1867 1870 { 1871 #if LGE_SAO_MIGRATION_D0091 1872 READ_FLAG(uiCode, "slice_sao_luma_flag"); rpcSlice->setSaoEnabledFlag((Bool)uiCode); 1873 READ_FLAG(uiCode, "slice_sao_chroma_flag"); rpcSlice->setSaoEnabledFlagChroma((Bool)uiCode); 1874 #else 1868 1875 READ_FLAG(uiCode, "slice_sao_interleaving_flag"); rpcSlice->setSaoInterleavingFlag(uiCode); 1869 1876 READ_FLAG(uiCode, "slice_sample_adaptive_offset_flag"); rpcSlice->setSaoEnabledFlag((Bool)uiCode); … … 1878 1885 rpcSlice->setSaoEnabledFlagCr(0); 1879 1886 } 1887 #endif 1880 1888 } 1881 1889 READ_UVLC ( uiCode, "aps_id" ); rpcSlice->setAPSId(uiCode); -
branches/HTM-6.2-dev1-LG/source/Lib/TLibDecoder/TDecCAVLC.h
r332 r408 177 177 protected: 178 178 Void xParseDblParam ( TComAPS* aps ); 179 #if !LGE_SAO_MIGRATION_D0091 179 180 Void xParseSaoParam ( SAOParam* pSaoParam ); 180 181 Void xParseSaoOffset (SaoLcuParam* saoLcuParam); 181 182 Void xParseSaoUnit (Int rx, Int ry, Int compIdx, SAOParam* saoParam, Bool& repeatedRow ); 183 #endif 182 184 Void xParseAlfParam(AlfParamSet* pAlfParamSet, Bool bSentInAPS = true, Int firstLCUAddr = 0, Bool acrossSlice = true, Int numLCUInWidth= -1, Int numLCUInHeight= -1); 183 185 Void parseAlfParamSet(AlfParamSet* pAlfParamSet, Int firstLCUAddr, Bool alfAcrossSlice); -
branches/HTM-6.2-dev1-LG/source/Lib/TLibDecoder/TDecCu.cpp
r384 r408 371 371 UInt uiMergeIndex = pcCU->getMergeIndex(uiAbsPartIdx); 372 372 #if MERL_VSP_C0152 373 #if LGE_VSP_INHERIT_D0092 374 Int iVSPIndexTrue[MRG_MAX_NUM_CANDS_MEM]; 375 for (Int i=0; i<MRG_MAX_NUM_CANDS_MEM; i++) 376 { 377 iVSPIndexTrue[i] = 0; 378 } 379 #else 373 380 Int iVSPIndexTrue[3] = {-1, -1, -1}; 381 #endif 374 382 m_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, uiMergeIndex ); 375 383 … … 383 391 { 384 392 Int iVSPIdx = 0; 393 #if LGE_VSP_INHERIT_D0092 394 if (iVSPIndexTrue[uiMergeIndex] == 1) 395 { 396 iVSPIdx = 1; 397 } 398 #else 385 399 Int numVspIdx; 386 400 numVspIdx = 3; … … 393 407 } 394 408 } 409 #endif 395 410 pcCU->setVSPIndexSubParts( iVSPIdx, uiAbsPartIdx, 0, uiDepth ); //Initialize the VSP, may change later in get InterMergeCandidates() 396 #if QC_BVSP_CleanUP_D0191 411 #if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092 397 412 if(iVSPIdx != 0) 398 413 { -
branches/HTM-6.2-dev1-LG/source/Lib/TLibDecoder/TDecEntropy.cpp
r384 r408 301 301 UInt uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); 302 302 #if MERL_VSP_C0152 303 #if LGE_VSP_INHERIT_D0092 304 Int iVSPIndexTrue[MRG_MAX_NUM_CANDS_MEM]; 305 for (Int i=0; i<MRG_MAX_NUM_CANDS_MEM; i++) 306 { 307 iVSPIndexTrue[i] = 0; 308 } 309 #else 303 310 Int iVSPIndexTrue[3] = {-1, -1, -1}; 311 #endif 304 312 pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue, uiMergeIndex ); 305 313 … … 326 334 { 327 335 Int iVSPIdx = 0; 336 #if LGE_VSP_INHERIT_D0092 337 if (iVSPIndexTrue[uiMergeIndex] == 1) 338 { 339 iVSPIdx = 1; 340 } 341 #else 328 342 Int numVspIdx; 329 343 numVspIdx = 3; … … 336 350 } 337 351 } 352 #endif 338 353 pcCU->setVSPIndexSubParts( iVSPIdx, uiSubPartIdx, uiPartIdx, uiDepth ); //Initialize the VSP, may change later in get InterMergeCandidates() 339 #if QC_BVSP_CleanUP_D0191 340 if(iVSPIdx != 0) 354 #if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092 355 if(iVSPIdx != 0) 341 356 { 342 357 Int iIVCIdx = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC()==pcCU->getSlice()->getPOC() ? 0: pcCU->getSlice()->getNewRefIdx(REF_PIC_LIST_0); -
branches/HTM-6.2-dev1-LG/source/Lib/TLibDecoder/TDecEntropy.h
r332 r408 225 225 Void setSliceGranularity (Int iSliceGranularity) {m_pcEntropyDecoderIf->setSliceGranularity(iSliceGranularity);} 226 226 227 #if !LGE_SAO_MIGRATION_D0091 227 228 Void decodeSaoParam (SAOParam* saoParam); 228 229 void decodeSaoLcu(Int rx, Int ry, Int compIdx, SAOParam* saoParam, Bool &repeatedRow ); 229 230 Void decodeSaoOneLcu(SaoLcuParam* saoLcuParam); 231 #endif 230 232 231 233 Void decodeFlush() { m_pcEntropyDecoderIf->decodeFlush(); } -
branches/HTM-6.2-dev1-LG/source/Lib/TLibDecoder/TDecGop.cpp
r296 r408 372 372 if( pcSlice->getSPS()->getUseSAO() ) 373 373 { 374 #if LGE_SAO_MIGRATION_D0091 375 if(pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) 376 { 377 SAOParam *saoParam = pcSlice->getAPS()->getSaoParam(); 378 saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag(); 379 saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma(); 380 m_pcSAO->setSaoLcuBasedOptimization(1); 381 m_pcSAO->createPicSaoInfo(rpcPic, m_uiILSliceCount); 382 m_pcSAO->SAOProcess(rpcPic, saoParam); 383 m_pcSAO->PCMLFDisableProcess(rpcPic); 384 m_pcSAO->destroyPicSaoInfo(); 385 } 386 #else 374 387 if(pcSlice->getSaoEnabledFlag()) 375 388 { … … 388 401 m_pcSAO->destroyPicSaoInfo(); 389 402 } 403 #endif 390 404 } 391 405 -
branches/HTM-6.2-dev1-LG/source/Lib/TLibDecoder/TDecSbac.cpp
r332 r408 88 88 , m_cALFSvlcSCModel ( 1, 1, NUM_ALF_SVLC_CTX , m_contextModels + m_numContextModels, m_numContextModels) 89 89 , m_cCUAMPSCModel ( 1, 1, NUM_CU_AMP_CTX , m_contextModels + m_numContextModels, m_numContextModels) 90 #if LGE_SAO_MIGRATION_D0091 91 , m_cSaoMergeSCModel ( 1, 1, NUM_SAO_MERGE_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) 92 , m_cSaoTypeIdxSCModel ( 1, 1, NUM_SAO_TYPE_IDX_CTX , m_contextModels + m_numContextModels, m_numContextModels) 93 #else 90 94 , m_cSaoFlagSCModel ( 1, 1, NUM_SAO_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) 91 95 , m_cSaoUvlcSCModel ( 1, 1, NUM_SAO_UVLC_CTX , m_contextModels + m_numContextModels, m_numContextModels) … … 94 98 , m_cSaoMergeUpSCModel ( 1, 1, NUM_SAO_MERGE_UP_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) 95 99 , m_cSaoTypeIdxSCModel ( 1, 1, NUM_SAO_TYPE_IDX_CTX , m_contextModels + m_numContextModels, m_numContextModels) 100 #endif 96 101 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX 97 102 , m_cDmmFlagSCModel ( 1, 1, NUM_DMM_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) … … 184 189 m_cALFUvlcSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_ALF_UVLC ); 185 190 m_cALFSvlcSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_ALF_SVLC ); 191 #if LGE_SAO_MIGRATION_D0091 192 m_cSaoMergeSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_SAO_MERGE_FLAG ); 193 m_cSaoTypeIdxSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_SAO_TYPE_IDX ); 194 #else 186 195 m_cSaoFlagSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_SAO_FLAG ); 187 196 m_cSaoUvlcSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_SAO_UVLC ); … … 190 199 m_cSaoMergeUpSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_SAO_MERGE_UP_FLAG ); 191 200 m_cSaoTypeIdxSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_SAO_TYPE_IDX ); 201 #endif 192 202 193 203 m_cCUTransSubdivFlagSCModel.initBuffer ( sliceType, qp, (UChar*)INIT_TRANS_SUBDIV_FLAG ); … … 271 281 m_cALFUvlcSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_ALF_UVLC ); 272 282 m_cALFSvlcSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_ALF_SVLC ); 283 #if LGE_SAO_MIGRATION_D0091 284 m_cSaoMergeSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_FLAG ); 285 m_cSaoTypeIdxSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX ); 286 #else 273 287 m_cSaoFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_FLAG ); 274 288 m_cSaoUvlcSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_UVLC ); … … 277 291 m_cSaoMergeUpSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_UP_FLAG ); 278 292 m_cSaoTypeIdxSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX ); 293 #endif 279 294 m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANS_SUBDIV_FLAG ); 280 295 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX … … 1672 1687 } 1673 1688 1674 1689 #if LGE_SAO_MIGRATION_D0091 1690 Void TDecSbac::parseSaoMaxUvlc ( UInt& val, UInt maxSymbol ) 1691 { 1692 if (maxSymbol == 0) 1693 { 1694 val = 0; 1695 return; 1696 } 1697 1698 UInt code; 1699 Int i; 1700 m_pcTDecBinIf->decodeBinEP( code ); 1701 if ( code == 0 ) 1702 { 1703 val = 0; 1704 return; 1705 } 1706 1707 i=1; 1708 while (1) 1709 { 1710 m_pcTDecBinIf->decodeBinEP( code ); 1711 if ( code == 0 ) 1712 { 1713 break; 1714 } 1715 i++; 1716 if (i == maxSymbol) 1717 { 1718 break; 1719 } 1720 } 1721 1722 val = i; 1723 } 1724 1725 Void TDecSbac::parseSaoUflc (UInt uiLength, UInt& riVal) 1726 { 1727 m_pcTDecBinIf->decodeBinsEP ( riVal, uiLength ); 1728 } 1729 1730 Void TDecSbac::parseSaoMerge (UInt& ruiVal) 1731 { 1732 UInt uiCode; 1733 m_pcTDecBinIf->decodeBin( uiCode, m_cSaoMergeSCModel.get( 0, 0, 0 ) ); 1734 ruiVal = (Int)uiCode; 1735 } 1736 1737 Void TDecSbac::parseSaoTypeIdx (UInt& ruiVal) 1738 { 1739 UInt uiCode; 1740 m_pcTDecBinIf->decodeBin( uiCode, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) ); 1741 if (uiCode == 0) 1742 { 1743 ruiVal = 0; 1744 } 1745 else 1746 { 1747 m_pcTDecBinIf->decodeBinEP( uiCode ); 1748 if (uiCode == 0) 1749 { 1750 ruiVal = 5; 1751 } 1752 else 1753 { 1754 ruiVal = 1; 1755 } 1756 } 1757 } 1758 1759 inline Void copySaoOneLcuParam(SaoLcuParam* psDst, SaoLcuParam* psSrc) 1760 { 1761 Int i; 1762 psDst->partIdx = psSrc->partIdx; 1763 psDst->typeIdx = psSrc->typeIdx; 1764 if (psDst->typeIdx != -1) 1765 { 1766 psDst->subTypeIdx = psSrc->subTypeIdx ; 1767 psDst->length = psSrc->length; 1768 for (i=0;i<psDst->length;i++) 1769 { 1770 psDst->offset[i] = psSrc->offset[i]; 1771 } 1772 } 1773 else 1774 { 1775 psDst->length = 0; 1776 for (i=0;i<SAO_BO_LEN;i++) 1777 { 1778 psDst->offset[i] = 0; 1779 } 1780 } 1781 } 1782 1783 Void TDecSbac::parseSaoOffset(SaoLcuParam* psSaoLcuParam, UInt compIdx) 1784 { 1785 UInt uiSymbol; 1786 static Int iTypeLength[MAX_NUM_SAO_TYPE] = 1787 { 1788 SAO_EO_LEN, 1789 SAO_EO_LEN, 1790 SAO_EO_LEN, 1791 SAO_EO_LEN, 1792 SAO_BO_LEN 1793 }; 1794 1795 if (compIdx==2) 1796 { 1797 uiSymbol = (UInt)( psSaoLcuParam->typeIdx + 1); 1798 } 1799 else 1800 { 1801 parseSaoTypeIdx(uiSymbol); 1802 } 1803 psSaoLcuParam->typeIdx = (Int)uiSymbol - 1; 1804 1805 if (uiSymbol) 1806 { 1807 psSaoLcuParam->length = iTypeLength[psSaoLcuParam->typeIdx]; 1808 #if FULL_NBIT 1809 Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + (g_uiBitDepth-8)-5),5) ); 1810 #else 1811 Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + g_uiBitIncrement-5),5) ); 1812 #endif 1813 1814 if( psSaoLcuParam->typeIdx == SAO_BO ) 1815 { 1816 for(Int i=0; i< psSaoLcuParam->length; i++) 1817 { 1818 parseSaoMaxUvlc(uiSymbol, offsetTh -1 ); 1819 psSaoLcuParam->offset[i] = uiSymbol; 1820 } 1821 for(Int i=0; i< psSaoLcuParam->length; i++) 1822 { 1823 if (psSaoLcuParam->offset[i] != 0) 1824 { 1825 m_pcTDecBinIf->decodeBinEP ( uiSymbol); 1826 if (uiSymbol) 1827 { 1828 psSaoLcuParam->offset[i] = -psSaoLcuParam->offset[i] ; 1829 } 1830 } 1831 } 1832 parseSaoUflc(5, uiSymbol ); 1833 psSaoLcuParam->subTypeIdx = uiSymbol; 1834 } 1835 else if( psSaoLcuParam->typeIdx < 4 ) 1836 { 1837 parseSaoMaxUvlc(uiSymbol, offsetTh -1 ); psSaoLcuParam->offset[0] = uiSymbol; 1838 parseSaoMaxUvlc(uiSymbol, offsetTh -1 ); psSaoLcuParam->offset[1] = uiSymbol; 1839 parseSaoMaxUvlc(uiSymbol, offsetTh -1 ); psSaoLcuParam->offset[2] = -(Int)uiSymbol; 1840 parseSaoMaxUvlc(uiSymbol, offsetTh -1 ); psSaoLcuParam->offset[3] = -(Int)uiSymbol; 1841 if (compIdx != 2) 1842 { 1843 parseSaoUflc(2, uiSymbol ); 1844 psSaoLcuParam->subTypeIdx = uiSymbol; 1845 psSaoLcuParam->typeIdx += psSaoLcuParam->subTypeIdx; 1846 } 1847 } 1848 } 1849 else 1850 { 1851 psSaoLcuParam->length = 0; 1852 } 1853 } 1854 1855 Void TDecSbac::parseSaoOneLcuInterleaving(Int rx, Int ry, SAOParam* pSaoParam, TComDataCU* pcCU, Int iCUAddrInSlice, Int iCUAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp) 1856 { 1857 Int iAddr = pcCU->getAddr(); 1858 UInt uiSymbol; 1859 1860 for (Int iCompIdx=0; iCompIdx<3; iCompIdx++) 1861 { 1862 pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeUpFlag = 0; 1863 pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeLeftFlag = 0; 1864 pSaoParam->saoLcuParam[iCompIdx][iAddr].subTypeIdx = 0; 1865 pSaoParam->saoLcuParam[iCompIdx][iAddr].typeIdx =-1; 1866 pSaoParam->saoLcuParam[iCompIdx][iAddr].offset[0] = 0; 1867 pSaoParam->saoLcuParam[iCompIdx][iAddr].offset[1] = 0; 1868 pSaoParam->saoLcuParam[iCompIdx][iAddr].offset[2] = 0; 1869 pSaoParam->saoLcuParam[iCompIdx][iAddr].offset[3] = 0; 1870 } 1871 if (pSaoParam->bSaoFlag[0] || pSaoParam->bSaoFlag[1] ) 1872 { 1873 if (rx>0 && iCUAddrInSlice!=0 && allowMergeLeft) 1874 { 1875 parseSaoMerge(uiSymbol); 1876 pSaoParam->saoLcuParam[0][iAddr].mergeLeftFlag = (Bool)uiSymbol; 1877 } 1878 if (pSaoParam->saoLcuParam[0][iAddr].mergeLeftFlag==0) 1879 { 1880 if ((ry > 0) && (iCUAddrUpInSlice>=0) && allowMergeUp) 1881 { 1882 parseSaoMerge(uiSymbol); 1883 pSaoParam->saoLcuParam[0][iAddr].mergeUpFlag = (Bool)uiSymbol; 1884 } 1885 } 1886 } 1887 1888 for (Int iCompIdx=0; iCompIdx<3; iCompIdx++) 1889 { 1890 if ((iCompIdx == 0 && pSaoParam->bSaoFlag[0]) || (iCompIdx > 0 && pSaoParam->bSaoFlag[1]) ) 1891 { 1892 if (rx>0 && iCUAddrInSlice!=0 && allowMergeLeft) 1893 { 1894 pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeLeftFlag = pSaoParam->saoLcuParam[0][iAddr].mergeLeftFlag; 1895 } 1896 else 1897 { 1898 pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeLeftFlag = 0; 1899 } 1900 1901 if (pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeLeftFlag==0) 1902 { 1903 if ((ry > 0) && (iCUAddrUpInSlice>=0) && allowMergeUp) 1904 { 1905 pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeUpFlag = pSaoParam->saoLcuParam[0][iAddr].mergeUpFlag; 1906 } 1907 else 1908 { 1909 pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeUpFlag = 0; 1910 } 1911 1912 if (!pSaoParam->saoLcuParam[iCompIdx][iAddr].mergeUpFlag) 1913 { 1914 pSaoParam->saoLcuParam[2][iAddr].typeIdx = pSaoParam->saoLcuParam[1][iAddr].typeIdx; 1915 parseSaoOffset(&(pSaoParam->saoLcuParam[iCompIdx][iAddr]), iCompIdx); 1916 } 1917 else 1918 { 1919 copySaoOneLcuParam(&pSaoParam->saoLcuParam[iCompIdx][iAddr], &pSaoParam->saoLcuParam[iCompIdx][iAddr-pSaoParam->numCuInWidth]); 1920 } 1921 } 1922 else 1923 { 1924 copySaoOneLcuParam(&pSaoParam->saoLcuParam[iCompIdx][iAddr], &pSaoParam->saoLcuParam[iCompIdx][iAddr-1]); 1925 } 1926 } 1927 else 1928 { 1929 pSaoParam->saoLcuParam[iCompIdx][iAddr].typeIdx = -1; 1930 pSaoParam->saoLcuParam[iCompIdx][iAddr].subTypeIdx = 0; 1931 } 1932 } 1933 } 1934 #else 1675 1935 Void TDecSbac::parseSaoUvlc (UInt& ruiVal) 1676 1936 { … … 1909 2169 } 1910 2170 } 2171 #endif 1911 2172 1912 2173 /** -
branches/HTM-6.2-dev1-LG/source/Lib/TLibDecoder/TDecSbac.h
r332 r408 110 110 #endif 111 111 112 #if LGE_SAO_MIGRATION_D0091 113 Void parseSaoMaxUvlc ( UInt& val, UInt maxSymbol ); 114 Void parseSaoMerge ( UInt& ruiVal ); 115 Void parseSaoTypeIdx ( UInt& ruiVal ); 116 Void parseSaoUflc ( UInt uiLength, UInt& ruiVal ); 117 Void parseSaoOneLcuInterleaving(Int rx, Int ry, SAOParam* pSaoParam, TComDataCU* pcCU, Int iCUAddrInSlice, Int iCUAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp); 118 Void parseSaoOffset (SaoLcuParam* psSaoLcuParam, UInt compIdx); 119 #else 112 120 Void parseSaoUvlc ( UInt& ruiVal ); 113 121 Void parseSaoSvlc ( Int& riVal ); … … 118 126 Void parseSaoOneLcuInterleaving(Int rx, Int ry, SAOParam* pSaoParam, TComDataCU* pcCU, Int iCUAddrInSlice, Int iCUAddrUpInSlice, Bool bLFCrossSliceBoundaryFlag); 119 127 Void parseSaoOffset (SaoLcuParam* psSaoLcuParam); 128 #endif 120 129 121 130 #if RWTH_SDC_DLT_B0036 … … 245 254 ContextModel3DBuffer m_cALFSvlcSCModel; 246 255 ContextModel3DBuffer m_cCUAMPSCModel; 256 #if LGE_SAO_MIGRATION_D0091 257 ContextModel3DBuffer m_cSaoMergeSCModel; 258 ContextModel3DBuffer m_cSaoTypeIdxSCModel; 259 #else 247 260 ContextModel3DBuffer m_cSaoFlagSCModel; 248 261 ContextModel3DBuffer m_cSaoUvlcSCModel; … … 251 264 ContextModel3DBuffer m_cSaoMergeUpSCModel; 252 265 ContextModel3DBuffer m_cSaoTypeIdxSCModel; 266 #endif 253 267 254 268 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX -
branches/HTM-6.2-dev1-LG/source/Lib/TLibDecoder/TDecSlice.cpp
r296 r408 286 286 g_bJustDoIt = g_bEncDecTraceEnable; 287 287 #endif 288 #if LGE_SAO_MIGRATION_D0091 289 if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) ) 290 { 291 SAOParam *saoParam = pcSlice->getAPS()->getSaoParam(); 292 saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag(); 293 if (iCUAddr == iStartCUAddr) 294 { 295 saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma(); 296 } 297 Int numCuInWidth = saoParam->numCuInWidth; 298 Int cuAddrInSlice = iCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU()); 299 Int cuAddrUpInSlice = cuAddrInSlice - numCuInWidth; 300 Int rx = iCUAddr % numCuInWidth; 301 Int ry = iCUAddr / numCuInWidth; 302 Int allowMergeLeft = 1; 303 Int allowMergeUp = 1; 304 if (rx!=0) 305 { 306 if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)) 307 { 308 allowMergeLeft = 0; 309 } 310 } 311 if (ry!=0) 312 { 313 if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-numCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)) 314 { 315 allowMergeUp = 0; 316 } 317 } 318 pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, saoParam,pcCU, cuAddrInSlice, cuAddrUpInSlice, allowMergeLeft, allowMergeUp); 319 } 320 #else 288 321 if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() ) 289 322 { … … 301 334 pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, cuAddrInSlice, cuAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag() ); 302 335 } 336 #endif 303 337 304 338 m_pcCuDecoder->decodeCU ( pcCU, uiIsLast ); -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncCavlc.cpp
r384 r408 972 972 if (pcSlice->getSPS()->getUseSAO()) 973 973 { 974 #if LGE_SAO_MIGRATION_D0091 975 WRITE_FLAG( pcSlice->getSaoEnabledFlag(), "slice_sao_luma_flag" ); 976 { 977 SAOParam *saoParam = pcSlice->getAPS()->getSaoParam(); 978 WRITE_FLAG( saoParam->bSaoFlag[1], "slice_sao_chroma_flag" ); 979 } 980 #else 974 981 WRITE_FLAG( pcSlice->getSaoInterleavingFlag(), "SAO interleaving flag" ); 975 982 assert (pcSlice->getSaoEnabledFlag() == pcSlice->getAPS()->getSaoEnabled()); … … 980 987 WRITE_FLAG( pcSlice->getAPS()->getSaoParam()->bSaoFlag[2], "SAO on/off flag for Cr in slice header" ); 981 988 } 989 #endif 982 990 } 983 991 WRITE_UVLC( pcSlice->getAPS()->getAPSID(), "aps_id"); … … 1506 1514 } 1507 1515 } 1508 1516 #if !LGE_SAO_MIGRATION_D0091 1509 1517 Void TEncCavlc::codeSaoFlag( UInt uiCode ) 1510 1518 { … … 1544 1552 WRITE_CODE( uiCode, uiLength, "sao_run_diff"); 1545 1553 } 1554 #endif 1546 1555 1547 1556 Void TEncCavlc::estBit( estBitsSbacStruct* pcEstBitsCabac, Int width, Int height, TextType eTType ) -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncCavlc.h
r332 r408 142 142 Void codeAPSAlflag(UInt uiCode); 143 143 Void codeAlfFixedLengthIdx( UInt idx, UInt numFilterSetsInBuffer); 144 #if LGE_SAO_MIGRATION_D0091 145 Void codeSAOSign ( UInt code ) { printf("Not supported\n"); assert (0); } 146 Void codeSaoMaxUvlc ( UInt code, UInt maxSymbol ){printf("Not supported\n"); assert (0);} 147 Void codeSaoMerge ( UInt uiCode ){printf("Not supported\n"); assert (0);} 148 Void codeSaoTypeIdx ( UInt uiCode ){printf("Not supported\n"); assert (0);} 149 Void codeSaoUflc ( UInt uiLength, UInt uiCode ){ assert(uiCode < 32); printf("Not supported\n"); assert (0);} 150 #else 144 151 Void codeSaoFlag ( UInt uiCode ); 145 152 Void codeSaoUvlc ( UInt uiCode ); … … 150 157 Void codeSaoTypeIdx ( UInt uiCode ){ xWriteUvlc(uiCode );} 151 158 Void codeSaoUflc ( UInt uiCode ){ assert(uiCode < 32); xWriteCode(uiCode, 5);} 159 #endif 152 160 153 161 Void codeSkipFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx ); -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncCfg.h
r384 r408 160 160 #endif 161 161 Int m_maxNumOffsetsPerPic; 162 #if LGE_SAO_MIGRATION_D0091 163 Bool m_saoLcuBoundary; 164 Bool m_saoLcuBasedOptimization; 165 #else 162 166 Bool m_saoInterleavingFlag; 167 #endif 163 168 164 169 //====== Lossless ======== … … 669 674 Void setMaxNumOffsetsPerPic (Int iVal) { m_maxNumOffsetsPerPic = iVal; } 670 675 Int getMaxNumOffsetsPerPic () { return m_maxNumOffsetsPerPic; } 676 #if LGE_SAO_MIGRATION_D0091 677 Void setSaoLcuBoundary (Bool val) { m_saoLcuBoundary = val; } 678 Bool getSaoLcuBoundary () { return m_saoLcuBoundary; } 679 Void setSaoLcuBasedOptimization (Bool val) { m_saoLcuBasedOptimization = val; } 680 Bool getSaoLcuBasedOptimization () { return m_saoLcuBasedOptimization; } 681 #else 671 682 Void setSaoInterleavingFlag (bool bVal) { m_saoInterleavingFlag = bVal; } 672 683 Bool getSaoInterleavingFlag () { return m_saoInterleavingFlag; } 684 #endif 673 685 Void setTileBehaviorControlPresentFlag ( Int i ) { m_iTileBehaviorControlPresentFlag = i; } 674 686 Int getTileBehaviorControlPresentFlag () { return m_iTileBehaviorControlPresentFlag; } -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncCu.cpp
r384 r408 1870 1870 rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level 1871 1871 #if MERL_VSP_C0152 1872 #if LGE_VSP_INHERIT_D0092 1873 Int iVSPIndexTrue[MRG_MAX_NUM_CANDS_MEM]; 1874 for (Int i=0; i<MRG_MAX_NUM_CANDS_MEM; i++) 1875 { 1876 iVSPIndexTrue[i] = 0; 1877 } 1878 #else 1872 1879 Int iVSPIndexTrue[3] = {-1, -1, -1}; 1880 #endif 1873 1881 rpcTempCU->getInterMergeCandidates( 0, 0, uhDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, iVSPIndexTrue ); 1874 1882 #else … … 1936 1944 { 1937 1945 Int iVSPIdx = 0; 1946 #if LGE_VSP_INHERIT_D0092 1947 if (iVSPIndexTrue[uiMergeCand] == 1) 1948 { 1949 iVSPIdx = 1; 1950 } 1951 #else 1938 1952 Int numVSPIdx; 1939 1953 numVSPIdx = 3; … … 1946 1960 } 1947 1961 } 1962 #endif 1948 1963 rpcTempCU->setVSPIndexSubParts( iVSPIdx, 0, 0, uhDepth ); 1949 #if QC_BVSP_CleanUP_D0191 1964 #if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092 1950 1965 if(iVSPIdx != 0) 1951 1966 { 1952 1967 Int iIVCIdx = rpcTempCU->getSlice()->getRefPic(REF_PIC_LIST_0, 0)->getPOC()==rpcTempCU->getSlice()->getPOC() ? 0: rpcTempCU->getSlice()->getNewRefIdx(REF_PIC_LIST_0); 1953 cMvFieldNeighbours[ 1968 cMvFieldNeighbours[2*uiMergeCand].setRefIdx(iIVCIdx); 1954 1969 } 1955 1970 #endif -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncEntropy.cpp
r348 r408 54 54 if (pcSlice->getSPS()->getUseSAO()) 55 55 { 56 #if LGE_SAO_MIGRATION_D0091 57 if (pcSlice->getSPS()->getUseSAO()) 58 { 59 SAOParam *saoParam = pcSlice->getAPS()->getSaoParam(); 60 pcSlice->setSaoEnabledFlag (saoParam->bSaoFlag[0]); 61 { 62 pcSlice->setSaoEnabledFlagChroma (saoParam->bSaoFlag[1]); 63 } 64 } 65 #else 56 66 pcSlice->setSaoInterleavingFlag(pcSlice->getAPS()->getSaoInterleavingFlag()); 57 67 pcSlice->setSaoEnabledFlag (pcSlice->getAPS()->getSaoParam()->bSaoFlag[0]); … … 66 76 pcSlice->setSaoEnabledFlagCr (0); 67 77 } 78 #endif 68 79 } 69 80 … … 1499 1510 } 1500 1511 1512 #if LGE_SAO_MIGRATION_D0091 1513 Void TEncEntropy::encodeSaoOffset(SaoLcuParam* saoLcuParam, UInt compIdx) 1514 { 1515 UInt uiSymbol; 1516 Int i; 1517 1518 uiSymbol = saoLcuParam->typeIdx + 1; 1519 if (compIdx!=2) 1520 { 1521 m_pcEntropyCoderIf->codeSaoTypeIdx(uiSymbol); 1522 } 1523 1524 if (uiSymbol) 1525 { 1526 if (saoLcuParam->typeIdx < 4 && compIdx != 2) 1527 { 1528 saoLcuParam->subTypeIdx = saoLcuParam->typeIdx; 1529 } 1530 #if FULL_NBIT 1531 Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + (g_uiBitDepth-8)-5),5) ); 1532 #else 1533 Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + g_uiBitIncrement-5),5) ); 1534 #endif 1535 if( saoLcuParam->typeIdx == SAO_BO ) 1536 { 1537 for( i=0; i< saoLcuParam->length; i++) 1538 { 1539 UInt absOffset = ( (saoLcuParam->offset[i] < 0) ? -saoLcuParam->offset[i] : saoLcuParam->offset[i]); 1540 m_pcEntropyCoderIf->codeSaoMaxUvlc(absOffset, offsetTh-1); 1541 } 1542 for( i=0; i< saoLcuParam->length; i++) 1543 { 1544 if (saoLcuParam->offset[i] != 0) 1545 { 1546 UInt sign = (saoLcuParam->offset[i] < 0) ? 1 : 0 ; 1547 m_pcEntropyCoderIf->codeSAOSign(sign); 1548 } 1549 } 1550 uiSymbol = (UInt) (saoLcuParam->subTypeIdx); 1551 m_pcEntropyCoderIf->codeSaoUflc(5, uiSymbol); 1552 } 1553 else if( saoLcuParam->typeIdx < 4 ) 1554 { 1555 m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[0], offsetTh-1); 1556 m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[1], offsetTh-1); 1557 m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[2], offsetTh-1); 1558 m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[3], offsetTh-1); 1559 1560 if (compIdx!=2) 1561 { 1562 uiSymbol = (UInt) (saoLcuParam->subTypeIdx); 1563 m_pcEntropyCoderIf->codeSaoUflc(2, uiSymbol); 1564 } 1565 } 1566 } 1567 } 1568 1569 /** Encode SAO unit interleaving 1570 * \param rx 1571 * \param ry 1572 * \param pSaoParam 1573 * \param pcCU 1574 * \param iCUAddrInSlice 1575 * \param iCUAddrUpInSlice 1576 * \param bLFCrossSliceBoundaryFlag 1577 */ 1578 Void TEncEntropy::encodeSaoUnitInterleaving(Int compIdx, Bool saoFlag, Int rx, Int ry, SaoLcuParam* saoLcuParam, Int cuAddrInSlice, Int cuAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp) 1579 { 1580 if (saoFlag) 1581 { 1582 if (rx>0 && cuAddrInSlice!=0 && allowMergeLeft) 1583 { 1584 m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeLeftFlag); 1585 } 1586 else 1587 { 1588 saoLcuParam->mergeLeftFlag = 0; 1589 } 1590 1591 if (saoLcuParam->mergeLeftFlag == 0) 1592 { 1593 if ( (ry > 0) && (cuAddrUpInSlice>=0) && allowMergeUp ) 1594 { 1595 m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeUpFlag); 1596 } 1597 else 1598 { 1599 saoLcuParam->mergeUpFlag = 0; 1600 } 1601 1602 if (!saoLcuParam->mergeUpFlag) 1603 { 1604 encodeSaoOffset(saoLcuParam, compIdx); 1605 } 1606 } 1607 } 1608 } 1609 #else 1501 1610 /** Encode SAO Offset 1502 1611 * \param saoLcuParam SAO LCU paramters … … 1686 1795 } 1687 1796 } 1797 #endif 1688 1798 1689 1799 Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize ) -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncEntropy.h
r332 r408 154 154 155 155 virtual Void codeAlfCtrlFlag ( UInt uiSymbol ) = 0; 156 #if LGE_SAO_MIGRATION_D0091 157 virtual Void codeSAOSign ( UInt code ) = 0; 158 virtual Void codeSaoMaxUvlc ( UInt code, UInt maxSymbol ) = 0; 159 virtual Void codeSaoMerge ( UInt uiCode ) = 0; 160 virtual Void codeSaoTypeIdx ( UInt uiCode) = 0; 161 virtual Void codeSaoUflc ( UInt uiLength, UInt uiCode ) = 0; 162 #else 156 163 virtual Void codeSaoFlag ( UInt uiCode ) = 0; 157 164 virtual Void codeSaoUvlc ( UInt uiCode ) = 0; … … 162 169 virtual Void codeSaoTypeIdx ( UInt uiCode) = 0; 163 170 virtual Void codeSaoUflc ( UInt uiCode) = 0; 171 #endif 164 172 virtual Void estBit (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, TextType eTType) = 0; 165 173 … … 310 318 Int golombEncode(int coeff, int k); 311 319 Int lengthGolomb(int coeffVal, int k); 320 #if LGE_SAO_MIGRATION_D0091 321 Void encodeSaoOffset(SaoLcuParam* saoLcuParam, UInt compIdx); 322 Void encodeSaoUnitInterleaving(Int compIdx, Bool saoFlag, Int rx, Int ry, SaoLcuParam* saoLcuParam, Int cuAddrInSlice, Int cuAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp); 323 #else 312 324 Void encodeSaoUnit(Int rx, Int ry, Int compIdx, SAOParam* saoParam, Int repeatedRow); 313 325 Void encodeSaoOffset(SaoLcuParam* saoLcuParam); 314 326 Void encodeSaoUnitInterleaving(Int rx, Int ry, SAOParam* saoParam, TComDataCU* cu, Int cuAddrInSlice, Int cuAddrUpInSlice, Bool lfCrossSliceBoundaryFlag); 315 327 Void encodeSaoParam (TComAPS* aps); 328 #endif 316 329 317 330 static Int countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize ); -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncGOP.cpp
r332 r408 1257 1257 TComAPS cAPS; 1258 1258 allocAPS(&cAPS, pcSlice->getSPS()); 1259 #if !LGE_SAO_MIGRATION_D0091 1259 1260 cAPS.setSaoInterleavingFlag(m_pcCfg->getSaoInterleavingFlag()); 1261 #endif 1260 1262 // set entropy coder for RD 1261 1263 m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice ); … … 1265 1267 m_pcEntropyCoder->resetEntropy(); 1266 1268 m_pcEntropyCoder->setBitstream( m_pcBitCounter ); 1269 #if LGE_SAO_MIGRATION_D0091 1270 m_pcSAO->startSaoEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), m_pcEncTop->getRDGoOnSbacCoder()); 1271 #else 1267 1272 m_pcSAO->startSaoEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), NULL); 1273 #endif 1268 1274 SAOParam& cSaoParam = *(cAPS.getSaoParam()); 1269 1275 1270 1276 #if SAO_CHROMA_LAMBDA 1277 #if LGE_SAO_MIGRATION_D0091 1278 #if SAO_ENCODING_CHOICE 1279 m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma(), pcPic->getSlice(0)->getDepth()); 1280 #else 1271 1281 m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma()); 1282 #endif 1283 #else 1284 m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma()); 1285 #endif 1272 1286 #else 1273 1287 #if ALF_CHROMA_LAMBDA … … 1554 1568 m_pcEntropyCoder->encodeDFParams(pcAPS); 1555 1569 } 1570 #if !LGE_SAO_MIGRATION_D0091 1556 1571 m_pcEntropyCoder->encodeSaoParam(pcAPS); 1572 #endif 1557 1573 m_pcEntropyCoder->encodeAPSAlfFlag( pcAPS->getAlfEnabled()?1:0); 1558 1574 if(pcAPS->getAlfEnabled()) -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp
r296 r408 43 43 //! \ingroup TLibEncoder 44 44 //! \{ 45 45 #if LGE_SAO_MIGRATION_D0091 46 46 TEncSampleAdaptiveOffset::TEncSampleAdaptiveOffset() 47 47 { 48 m_pcEntropyCoder = NULL; 49 m_pppcRDSbacCoder = NULL; 50 m_pcRDGoOnSbacCoder = NULL; 51 m_pppcBinCoderCABAC = NULL; 52 m_iCount = NULL; 53 m_iOffset = NULL; 54 m_iOffsetOrg = NULL; 55 m_iRate = NULL; 56 m_iDist = NULL; 57 m_dCost = NULL; 58 m_dCostPartBest = NULL; 59 m_iDistOrg = NULL; 60 m_iTypePartBest = NULL; 61 } 48 m_pcEntropyCoder= NULL; 49 m_pppcRDSbacCoder = NULL; 50 m_pcRDGoOnSbacCoder = NULL; 51 m_pppcBinCoderCABAC = NULL; 52 m_iCount = NULL; 53 m_iOffset = NULL; 54 m_iOffsetOrg = NULL; 55 m_iRate = NULL; 56 m_iDist = NULL; 57 m_dCost = NULL; 58 m_dCostPartBest = NULL; 59 m_iDistOrg = NULL; 60 m_iTypePartBest = NULL; 61 #if SAO_ENCODING_CHOICE_CHROMA 62 m_depthSaoRate[0][0] = 0; 63 m_depthSaoRate[0][1] = 0; 64 m_depthSaoRate[0][2] = 0; 65 m_depthSaoRate[0][3] = 0; 66 m_depthSaoRate[1][0] = 0; 67 m_depthSaoRate[1][1] = 0; 68 m_depthSaoRate[1][2] = 0; 69 m_depthSaoRate[1][3] = 0; 70 #endif 71 } 72 62 73 TEncSampleAdaptiveOffset::~TEncSampleAdaptiveOffset() 63 74 { … … 76 87 { 77 88 #if FULL_NBIT 78 Int bitDepthMinus8 = g_uiBitDepth - 8;79 return ((x)>0) ? (Int)(((Int)(x)+(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)) : ((Int)(((Int)(x)-(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)));89 Int bitDepthMinus8 = g_uiBitDepth - 8; 90 return ((x)>0) ? (Int)(((Int)(x)+(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)) : ((Int)(((Int)(x)-(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8))); 80 91 #else 81 return ((x)>0) ? (Int)(((Int)(x)+(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)) : ((Int)(((Int)(x)-(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)));92 return ((x)>0) ? (Int)(((Int)(x)+(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)) : ((Int)(((Int)(x)-(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement))); 82 93 #endif 83 94 } … … 89 100 { 90 101 #if FULL_NBIT 91 return (g_uiBitDepth > 8 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ;102 return (g_uiBitDepth > 8 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ; 92 103 #else 93 return (g_uiBitIncrement >0 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ; 94 #endif 95 } 96 97 104 return (g_uiBitIncrement >0 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ; 105 #endif 106 } 98 107 99 108 /** process SAO for one partition 100 109 * \param *psQTPart, iPartIdx, dLambda 101 110 */ 102 Void TEncSampleAdaptiveOffset::rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda) 103 { 104 Int iTypeIdx; 105 Int iNumTotalType = MAX_NUM_SAO_TYPE; 106 SAOQTPart* pOnePart = &(psQTPart[iPartIdx]); 107 108 Int64 iEstDist; 109 Int64 iOffsetOrg; 110 Int64 iOffset; 111 Int64 iCount; 112 Int iClassIdx; 113 Int uiShift = g_uiBitIncrement << 1; 114 UInt uiDepth = pOnePart->PartLevel; 115 116 m_iDistOrg [iPartIdx] = 0; 117 118 Double bestRDCostTableBo = MAX_DOUBLE; 119 Int bestClassTableBo = 0; 120 Int currentDistortionTableBo[MAX_NUM_SAO_CLASS]; 121 Double currentRdCostTableBo[MAX_NUM_SAO_CLASS]; 122 123 #if HHI_INTERVIEW_SKIP 124 Int iFrameWidthInCU = m_pcPic->getFrameWidthInCU(); 125 Int LcuIdxX = psQTPart->StartCUX; 126 Int LcuIdxY = psQTPart->StartCUY; 127 Int iAddr = LcuIdxY*iFrameWidthInCU + LcuIdxX; 128 TComDataCU *pcCU = m_pcPic->getCU(iAddr); 129 Bool bRenderable = pcCU->getRenderable(0) ; 130 131 #endif 132 for (iTypeIdx=-1; iTypeIdx<iNumTotalType; iTypeIdx++) 133 { 134 if( m_bUseSBACRD ) 135 { 136 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]); 137 m_pcRDGoOnSbacCoder->resetBits(); 111 Void TEncSampleAdaptiveOffset::rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda, Int yCbCr) 112 { 113 Int iTypeIdx; 114 Int iNumTotalType = MAX_NUM_SAO_TYPE; 115 SAOQTPart* pOnePart = &(psQTPart[iPartIdx]); 116 117 Int64 iEstDist; 118 Int iClassIdx; 119 Int uiShift = g_uiBitIncrement << 1; 120 UInt uiDepth = pOnePart->PartLevel; 121 122 m_iDistOrg [iPartIdx] = 0; 123 124 Double bestRDCostTableBo = MAX_DOUBLE; 125 Int bestClassTableBo = 0; 126 Int currentDistortionTableBo[MAX_NUM_SAO_CLASS]; 127 Double currentRdCostTableBo[MAX_NUM_SAO_CLASS]; 128 129 Int addr; 130 Int allowMergeLeft; 131 Int allowMergeUp; 132 Int frameWidthInCU = m_pcPic->getFrameWidthInCU(); 133 SaoLcuParam saoLcuParamRdo; 134 135 for (iTypeIdx=-1; iTypeIdx<iNumTotalType; iTypeIdx++) 136 { 137 if( m_bUseSBACRD ) 138 { 139 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]); 140 m_pcRDGoOnSbacCoder->resetBits(); 141 } 142 else 143 { 144 m_pcEntropyCoder->resetEntropy(); 145 m_pcEntropyCoder->resetBits(); 146 } 147 148 iEstDist = 0; 149 150 if (iTypeIdx == -1) 151 { 152 for (Int ry = pOnePart->StartCUY; ry<= pOnePart->EndCUY; ry++) 153 { 154 for (Int rx = pOnePart->StartCUX; rx <= pOnePart->EndCUX; rx++) 155 { 156 addr = ry * frameWidthInCU + rx; 157 // get bits for iTypeIdx = -1 158 allowMergeLeft = 1; 159 allowMergeUp = 1; 160 if (rx != 0) 161 { 162 // check tile id and slice id 163 if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-1) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-1)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx())) 164 { 165 allowMergeLeft = 0; 166 } 167 } 168 if (ry!=0) 169 { 170 if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-m_iNumCuInWidth) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-m_iNumCuInWidth)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx())) 171 { 172 allowMergeUp = 0; 173 } 174 } 175 176 // reset 177 resetSaoUnit(&saoLcuParamRdo); 178 179 // set merge flag 180 saoLcuParamRdo.mergeUpFlag = 1; 181 saoLcuParamRdo.mergeLeftFlag = 1; 182 183 if (ry == pOnePart->StartCUY) 184 { 185 saoLcuParamRdo.mergeUpFlag = 0; 186 } 187 188 if (rx == pOnePart->StartCUX) 189 { 190 saoLcuParamRdo.mergeLeftFlag = 0; 191 } 192 193 m_pcEntropyCoder->encodeSaoUnitInterleaving(yCbCr, 1, rx, ry, &saoLcuParamRdo, 1, 1, allowMergeLeft, allowMergeUp); 194 195 } 196 } 197 } 198 199 if (iTypeIdx>=0) 200 { 201 iEstDist = estSaoTypeDist(iPartIdx, iTypeIdx, uiShift, dLambda, currentDistortionTableBo, currentRdCostTableBo); 202 if( iTypeIdx == SAO_BO ) 203 { 204 // Estimate Best Position 205 Double currentRDCost = 0.0; 206 207 for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++) 208 { 209 currentRDCost = 0.0; 210 for(UInt uj = i; uj < i+SAO_BO_LEN; uj++) 211 { 212 currentRDCost += currentRdCostTableBo[uj]; 213 } 214 215 if( currentRDCost < bestRDCostTableBo) 216 { 217 bestRDCostTableBo = currentRDCost; 218 bestClassTableBo = i; 219 } 220 } 221 222 // Re code all Offsets 223 // Code Center 224 for(iClassIdx = bestClassTableBo; iClassIdx < bestClassTableBo+SAO_BO_LEN; iClassIdx++) 225 { 226 iEstDist += currentDistortionTableBo[iClassIdx]; 227 } 228 } 229 230 for (Int ry = pOnePart->StartCUY; ry<= pOnePart->EndCUY; ry++) 231 { 232 for (Int rx = pOnePart->StartCUX; rx <= pOnePart->EndCUX; rx++) 233 { 234 addr = ry * frameWidthInCU + rx; 235 236 // get bits for iTypeIdx = -1 237 allowMergeLeft = 1; 238 allowMergeUp = 1; 239 if (rx != 0) 240 { 241 // check tile id and slice id 242 if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-1) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-1)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx())) 243 { 244 allowMergeLeft = 0; 245 } 246 } 247 if (ry!=0) 248 { 249 if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-m_iNumCuInWidth) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-m_iNumCuInWidth)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx())) 250 { 251 allowMergeUp = 0; 252 } 253 } 254 255 // reset 256 resetSaoUnit(&saoLcuParamRdo); 257 258 // set merge flag 259 saoLcuParamRdo.mergeUpFlag = 1; 260 saoLcuParamRdo.mergeLeftFlag = 1; 261 262 if (ry == pOnePart->StartCUY) 263 { 264 saoLcuParamRdo.mergeUpFlag = 0; 265 } 266 267 if (rx == pOnePart->StartCUX) 268 { 269 saoLcuParamRdo.mergeLeftFlag = 0; 270 } 271 272 // set type and offsets 273 saoLcuParamRdo.typeIdx = iTypeIdx; 274 saoLcuParamRdo.subTypeIdx = (iTypeIdx==SAO_BO)?bestClassTableBo:0; 275 saoLcuParamRdo.length = m_iNumClass[iTypeIdx]; 276 for (iClassIdx = 0; iClassIdx < saoLcuParamRdo.length; iClassIdx++) 277 { 278 saoLcuParamRdo.offset[iClassIdx] = (Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx+saoLcuParamRdo.subTypeIdx+1]; 279 } 280 281 m_pcEntropyCoder->encodeSaoUnitInterleaving(yCbCr, 1, rx, ry, &saoLcuParamRdo, 1, 1, allowMergeLeft, allowMergeUp); 282 283 } 284 } 285 286 m_iDist[iPartIdx][iTypeIdx] = iEstDist; 287 m_iRate[iPartIdx][iTypeIdx] = m_pcEntropyCoder->getNumberOfWrittenBits(); 288 289 m_dCost[iPartIdx][iTypeIdx] = (Double)((Double)m_iDist[iPartIdx][iTypeIdx] + dLambda * (Double) m_iRate[iPartIdx][iTypeIdx]); 290 291 if(m_dCost[iPartIdx][iTypeIdx] < m_dCostPartBest[iPartIdx]) 292 { 293 m_iDistOrg [iPartIdx] = 0; 294 m_dCostPartBest[iPartIdx] = m_dCost[iPartIdx][iTypeIdx]; 295 m_iTypePartBest[iPartIdx] = iTypeIdx; 296 if( m_bUseSBACRD ) 297 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] ); 298 } 299 } 300 else 301 { 302 if(m_iDistOrg[iPartIdx] < m_dCostPartBest[iPartIdx] ) 303 { 304 m_dCostPartBest[iPartIdx] = (Double) m_iDistOrg[iPartIdx] + m_pcEntropyCoder->getNumberOfWrittenBits()*dLambda ; 305 m_iTypePartBest[iPartIdx] = -1; 306 if( m_bUseSBACRD ) 307 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] ); 308 } 309 } 310 } 311 312 pOnePart->bProcessed = true; 313 pOnePart->bSplit = false; 314 pOnePart->iMinDist = m_iTypePartBest[iPartIdx] >= 0 ? m_iDist[iPartIdx][m_iTypePartBest[iPartIdx]] : m_iDistOrg[iPartIdx]; 315 pOnePart->iMinRate = (Int) (m_iTypePartBest[iPartIdx] >= 0 ? m_iRate[iPartIdx][m_iTypePartBest[iPartIdx]] : 0); 316 pOnePart->dMinCost = pOnePart->iMinDist + dLambda * pOnePart->iMinRate; 317 pOnePart->iBestType = m_iTypePartBest[iPartIdx]; 318 if (pOnePart->iBestType != -1) 319 { 320 // pOnePart->bEnableFlag = 1; 321 pOnePart->iLength = m_iNumClass[pOnePart->iBestType]; 322 Int minIndex = 0; 323 if( pOnePart->iBestType == SAO_BO ) 324 { 325 pOnePart->subTypeIdx = bestClassTableBo; 326 minIndex = pOnePart->subTypeIdx; 327 } 328 for (Int i=0; i< pOnePart->iLength ; i++) 329 { 330 pOnePart->iOffset[i] = (Int) m_iOffset[iPartIdx][pOnePart->iBestType][minIndex+i+1]; 331 } 332 138 333 } 139 334 else 140 335 { 141 m_pcEntropyCoder->resetEntropy(); 142 m_pcEntropyCoder->resetBits(); 143 } 144 145 iEstDist = 0; 146 147 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoTypeIdx(iTypeIdx+1); 148 149 if (iTypeIdx>=0) 150 { 151 152 for(iClassIdx=1; iClassIdx < ( (iTypeIdx < SAO_BO) ? m_iNumClass[iTypeIdx]+1 : SAO_MAX_BO_CLASSES+1); iClassIdx++) 153 { 154 if( iTypeIdx == SAO_BO) 155 { 156 currentDistortionTableBo[iClassIdx-1] = 0; 157 currentRdCostTableBo[iClassIdx-1] = dLambda; 158 } 159 #if HHI_INTERVIEW_SKIP 160 if(m_iCount [iPartIdx][iTypeIdx][iClassIdx] && !bRenderable) 161 #else 162 if(m_iCount [iPartIdx][iTypeIdx][iClassIdx]) 163 #endif 164 { 165 #if FULL_NBIT 166 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]<<g_uiBitDepth-8) / (Double)(m_iCount [iPartIdx][iTypeIdx][iClassIdx]<<m_uiSaoBitIncrease)); 167 #else 168 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]<<g_uiBitIncrement) / (Double)(m_iCount [iPartIdx][iTypeIdx][iClassIdx]<<m_uiSaoBitIncrease)); 169 #endif 170 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = Clip3(-m_iOffsetTh, m_iOffsetTh-1, (Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]); 171 172 if (iTypeIdx < 4) 173 { 174 if ( m_iOffset[iPartIdx][iTypeIdx][iClassIdx]<0 && iClassIdx<3 ) 175 { 176 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0; 177 } 178 if ( m_iOffset[iPartIdx][iTypeIdx][iClassIdx]>0 && iClassIdx>=3) 179 { 180 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0; 181 } 182 } 183 { 184 //Clean up, best_q_offset. 185 Int64 iIterOffset, iTempOffset; 186 Int64 iTempDist, iTempRate; 187 Double dTempCost, dTempMinCost; 188 UInt uiLength, uiTemp; 189 190 iIterOffset = m_iOffset[iPartIdx][iTypeIdx][iClassIdx]; 191 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0; 192 dTempMinCost = dLambda; // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here. 193 194 while (iIterOffset != 0) 195 { 196 // Calculate the bits required for signalling the offset 197 uiLength = 1; 198 uiTemp = (UInt)((iIterOffset <= 0) ? ( (-iIterOffset<<1) + 1 ) : (iIterOffset<<1)); 199 while( 1 != uiTemp ) 200 { 201 uiTemp >>= 1; 202 uiLength += 2; 203 } 204 iTempRate = (uiLength >> 1) + ((uiLength+1) >> 1); 205 206 // Do the dequntization before distorion calculation 207 iTempOffset = iIterOffset << m_uiSaoBitIncrease; 208 iTempDist = (( m_iCount [iPartIdx][iTypeIdx][iClassIdx]*iTempOffset*iTempOffset-m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]*iTempOffset*2 ) >> uiShift); 209 210 dTempCost = ((Double)iTempDist + dLambda * (Double) iTempRate); 211 if(dTempCost < dTempMinCost) 212 { 213 dTempMinCost = dTempCost; 214 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = iIterOffset; 215 if(iTypeIdx == SAO_BO) 216 { 217 currentDistortionTableBo[iClassIdx-1] = (Int) iTempDist; 218 currentRdCostTableBo[iClassIdx-1] = dTempCost; 219 } 220 } 221 iIterOffset = (iIterOffset > 0) ? (iIterOffset-1):(iIterOffset+1); 222 } 223 224 } 225 } 226 else 227 { 228 m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx] = 0; 229 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0; 230 } 231 if( iTypeIdx != SAO_BO ) 232 { 233 iCount = m_iCount [iPartIdx][iTypeIdx][iClassIdx]; 234 iOffset = m_iOffset[iPartIdx][iTypeIdx][iClassIdx] << m_uiSaoBitIncrease; 235 iOffsetOrg = m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]; 236 iEstDist += (( iCount*iOffset*iOffset-iOffsetOrg*iOffset*2 ) >> uiShift); 237 if (iTypeIdx < 4) 238 { 239 if (iClassIdx<3) 240 { 241 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]); 242 } 243 else 244 { 245 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUvlc((Int)-m_iOffset[iPartIdx][iTypeIdx][iClassIdx]); 246 } 247 } 248 else 249 { 250 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoSvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]); 251 } 252 } 253 } 254 255 if( iTypeIdx == SAO_BO ) 256 { 257 // Estimate Best Position 258 Double currentRDCost = 0.0; 259 260 for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++) 261 { 262 currentRDCost = 0.0; 263 for(UInt uj = i; uj < i+SAO_BO_LEN; uj++) 264 { 265 currentRDCost += currentRdCostTableBo[uj]; 266 } 267 268 if( currentRDCost < bestRDCostTableBo) 269 { 270 bestRDCostTableBo = currentRDCost; 271 bestClassTableBo = i; 272 } 273 } 274 275 // Re code all Offsets 276 // Code Center 277 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUflc( (UInt) (bestClassTableBo) ); 278 279 for(iClassIdx = bestClassTableBo; iClassIdx < bestClassTableBo+SAO_BO_LEN; iClassIdx++) 280 { 281 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoSvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx+1]); 282 iEstDist += currentDistortionTableBo[iClassIdx]; 283 } 284 } 285 286 m_iDist[iPartIdx][iTypeIdx] = iEstDist; 287 m_iRate[iPartIdx][iTypeIdx] = m_pcEntropyCoder->getNumberOfWrittenBits(); 288 289 m_dCost[iPartIdx][iTypeIdx] = (Double)((Double)m_iDist[iPartIdx][iTypeIdx] + dLambda * (Double) m_iRate[iPartIdx][iTypeIdx]); 290 291 if(m_dCost[iPartIdx][iTypeIdx] < m_dCostPartBest[iPartIdx]) 292 { 293 m_iDistOrg [iPartIdx] = 0; 294 m_dCostPartBest[iPartIdx] = m_dCost[iPartIdx][iTypeIdx]; 295 m_iTypePartBest[iPartIdx] = iTypeIdx; 296 if( m_bUseSBACRD ) 297 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] ); 298 } 299 } 300 else 301 { 302 if(m_iDistOrg[iPartIdx] < m_dCostPartBest[iPartIdx] ) 303 { 304 m_dCostPartBest[iPartIdx] = (Double) m_iDistOrg[iPartIdx] + m_pcEntropyCoder->getNumberOfWrittenBits()*dLambda ; 305 m_iTypePartBest[iPartIdx] = -1; 306 if( m_bUseSBACRD ) 307 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] ); 308 } 309 } 310 } 311 312 pOnePart->bProcessed = true; 313 pOnePart->bSplit = false; 314 pOnePart->iMinDist = m_iTypePartBest[iPartIdx] >= 0 ? m_iDist[iPartIdx][m_iTypePartBest[iPartIdx]] : m_iDistOrg[iPartIdx]; 315 pOnePart->iMinRate = (Int) (m_iTypePartBest[iPartIdx] >= 0 ? m_iRate[iPartIdx][m_iTypePartBest[iPartIdx]] : 0); 316 pOnePart->dMinCost = pOnePart->iMinDist + dLambda * pOnePart->iMinRate; 317 pOnePart->iBestType = m_iTypePartBest[iPartIdx]; 318 if (pOnePart->iBestType != -1) 319 { 320 // pOnePart->bEnableFlag = 1; 321 pOnePart->iLength = m_iNumClass[pOnePart->iBestType]; 322 Int minIndex = 0; 323 if( pOnePart->iBestType == SAO_BO ) 324 { 325 pOnePart->bandPosition = bestClassTableBo; 326 minIndex = pOnePart->bandPosition; 327 } 328 for (Int i=0; i< pOnePart->iLength ; i++) 329 { 330 pOnePart->iOffset[i] = (Int) m_iOffset[iPartIdx][pOnePart->iBestType][minIndex+i+1]; 331 } 332 333 } 334 else 335 { 336 // pOnePart->bEnableFlag = 0; 337 pOnePart->iLength = 0; 338 } 336 // pOnePart->bEnableFlag = 0; 337 pOnePart->iLength = 0; 338 } 339 339 } 340 340 … … 343 343 Void TEncSampleAdaptiveOffset::disablePartTree(SAOQTPart *psQTPart, Int iPartIdx) 344 344 { 345 SAOQTPart* pOnePart= &(psQTPart[iPartIdx]);346 pOnePart->bSplit = false;347 pOnePart->iLength = 0;348 pOnePart->iBestType = -1;349 350 if (pOnePart->PartLevel < m_uiMaxSplitLevel)351 {352 for (Int i=0; i<NUM_DOWN_PART; i++)353 {354 disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]);355 }356 }345 SAOQTPart* pOnePart= &(psQTPart[iPartIdx]); 346 pOnePart->bSplit = false; 347 pOnePart->iLength = 0; 348 pOnePart->iBestType = -1; 349 350 if (pOnePart->PartLevel < m_uiMaxSplitLevel) 351 { 352 for (Int i=0; i<NUM_DOWN_PART; i++) 353 { 354 disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]); 355 } 356 } 357 357 } 358 358 … … 360 360 * \param iPartIdx, pcPicOrg, pcPicDec, pcPicRest, &dCostFinal 361 361 */ 362 Void TEncSampleAdaptiveOffset::runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda) 363 { 364 SAOQTPart* pOnePart = &(psQTPart[iPartIdx]); 365 366 UInt uiDepth = pOnePart->PartLevel; 367 UInt uhNextDepth = uiDepth+1; 368 369 if (iPartIdx == 0) 370 { 371 dCostFinal = 0; 372 } 373 374 //SAO for this part 375 if(!pOnePart->bProcessed) 376 { 377 rdoSaoOnePart (psQTPart, iPartIdx, dLambda); 378 } 379 380 //SAO for sub 4 parts 381 if (pOnePart->PartLevel < iMaxLevel) 382 { 383 Double dCostNotSplit = dLambda + pOnePart->dMinCost; 384 Double dCostSplit = dLambda; 385 386 for (Int i=0; i< NUM_DOWN_PART ;i++) 387 { 388 if( m_bUseSBACRD ) 389 { 390 if ( 0 == i) //initialize RD with previous depth buffer 391 { 392 m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]); 362 Void TEncSampleAdaptiveOffset::runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda, Int yCbCr) 363 { 364 SAOQTPart* pOnePart = &(psQTPart[iPartIdx]); 365 366 UInt uiDepth = pOnePart->PartLevel; 367 UInt uhNextDepth = uiDepth+1; 368 369 if (iPartIdx == 0) 370 { 371 dCostFinal = 0; 372 } 373 374 //SAO for this part 375 if(!pOnePart->bProcessed) 376 { 377 rdoSaoOnePart (psQTPart, iPartIdx, dLambda, yCbCr); 378 } 379 380 //SAO for sub 4 parts 381 if (pOnePart->PartLevel < iMaxLevel) 382 { 383 Double dCostNotSplit = dLambda + pOnePart->dMinCost; 384 Double dCostSplit = dLambda; 385 386 for (Int i=0; i< NUM_DOWN_PART ;i++) 387 { 388 if( m_bUseSBACRD ) 389 { 390 if ( 0 == i) //initialize RD with previous depth buffer 391 { 392 m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]); 393 } 394 else 395 { 396 m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]); 397 } 398 } 399 runQuadTreeDecision(psQTPart, pOnePart->DownPartsIdx[i], dCostFinal, iMaxLevel, dLambda, yCbCr); 400 dCostSplit += dCostFinal; 401 if( m_bUseSBACRD ) 402 { 403 m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_TEMP_BEST]); 404 } 405 } 406 407 if(dCostSplit < dCostNotSplit) 408 { 409 dCostFinal = dCostSplit; 410 pOnePart->bSplit = true; 411 pOnePart->iLength = 0; 412 pOnePart->iBestType = -1; 413 if( m_bUseSBACRD ) 414 { 415 m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]); 416 } 393 417 } 394 418 else 395 419 { 396 m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]); 397 } 398 } 399 runQuadTreeDecision(psQTPart, pOnePart->DownPartsIdx[i], dCostFinal, iMaxLevel, dLambda); 400 dCostSplit += dCostFinal; 401 if( m_bUseSBACRD ) 402 { 403 m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_TEMP_BEST]); 404 } 405 } 406 407 if(dCostSplit < dCostNotSplit) 408 { 409 dCostFinal = dCostSplit; 410 pOnePart->bSplit = true; 411 pOnePart->iLength = 0; 412 pOnePart->iBestType = -1; 413 if( m_bUseSBACRD ) 414 { 415 m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]); 416 } 420 dCostFinal = dCostNotSplit; 421 pOnePart->bSplit = false; 422 for (Int i=0; i<NUM_DOWN_PART; i++) 423 { 424 disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]); 425 } 426 if( m_bUseSBACRD ) 427 { 428 m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]); 429 } 430 } 417 431 } 418 432 else 419 433 { 420 dCostFinal = dCostNotSplit; 421 pOnePart->bSplit = false; 422 for (Int i=0; i<NUM_DOWN_PART; i++) 423 { 424 disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]); 425 } 426 if( m_bUseSBACRD ) 427 { 428 m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]); 429 } 430 } 431 } 432 else 433 { 434 dCostFinal = pOnePart->dMinCost; 435 } 434 dCostFinal = pOnePart->dMinCost; 435 } 436 436 } 437 437 … … 446 446 if (m_iCount [i][j]) 447 447 { 448 delete [] m_iCount [i][j]; 448 delete [] m_iCount [i][j]; 449 449 } 450 450 if (m_iOffset[i][j]) … … 454 454 if (m_iOffsetOrg[i][j]) 455 455 { 456 delete [] m_iOffsetOrg[i][j]; 456 delete [] m_iOffsetOrg[i][j]; 457 457 } 458 458 } … … 463 463 if (m_iDist[i]) 464 464 { 465 delete [] m_iDist[i]; 465 delete [] m_iDist[i]; 466 466 } 467 467 if (m_dCost[i]) … … 471 471 if (m_iCount [i]) 472 472 { 473 delete [] m_iCount [i]; 473 delete [] m_iCount [i]; 474 474 } 475 475 if (m_iOffset[i]) … … 479 479 if (m_iOffsetOrg[i]) 480 480 { 481 delete [] m_iOffsetOrg[i]; 482 } 483 481 delete [] m_iOffsetOrg[i]; 482 } 484 483 } 485 484 if (m_iDistOrg) … … 518 517 { 519 518 delete [] m_iOffsetOrg ; m_iOffsetOrg = NULL; 519 } 520 Int numLcu = m_iNumCuInWidth * m_iNumCuInHeight; 521 522 for (Int i=0;i<numLcu;i++) 523 { 524 for (Int j=0;j<3;j++) 525 { 526 for (Int k=0;k<MAX_NUM_SAO_TYPE;k++) 527 { 528 if (m_count_PreDblk [i][j][k]) 529 { 530 delete [] m_count_PreDblk [i][j][k]; 531 } 532 if (m_offsetOrg_PreDblk[i][j][k]) 533 { 534 delete [] m_offsetOrg_PreDblk[i][j][k]; 535 } 536 } 537 if (m_count_PreDblk [i][j]) 538 { 539 delete [] m_count_PreDblk [i][j]; 540 } 541 if (m_offsetOrg_PreDblk[i][j]) 542 { 543 delete [] m_offsetOrg_PreDblk[i][j]; 544 } 545 } 546 if (m_count_PreDblk [i]) 547 { 548 delete [] m_count_PreDblk [i]; 549 } 550 if (m_offsetOrg_PreDblk[i]) 551 { 552 delete [] m_offsetOrg_PreDblk[i]; 553 } 554 } 555 if (m_count_PreDblk) 556 { 557 delete [] m_count_PreDblk ; m_count_PreDblk = NULL; 558 } 559 if (m_offsetOrg_PreDblk) 560 { 561 delete [] m_offsetOrg_PreDblk ; m_offsetOrg_PreDblk = NULL; 520 562 } 521 563 … … 546 588 Void TEncSampleAdaptiveOffset::createEncBuffer() 547 589 { 548 m_iDistOrg = new Int64 [m_iNumTotalParts]; 549 m_dCostPartBest = new Double [m_iNumTotalParts]; 550 m_iTypePartBest = new Int [m_iNumTotalParts]; 590 m_iDistOrg = new Int64 [m_iNumTotalParts]; 591 m_dCostPartBest = new Double [m_iNumTotalParts]; 592 m_iTypePartBest = new Int [m_iNumTotalParts]; 551 593 552 594 m_iRate = new Int64* [m_iNumTotalParts]; … … 561 603 { 562 604 m_iRate[i] = new Int64 [MAX_NUM_SAO_TYPE]; 563 m_iDist[i] = new Int64 [MAX_NUM_SAO_TYPE]; 564 m_dCost[i] = new Double [MAX_NUM_SAO_TYPE]; 565 566 m_iCount [i] = new Int64 *[MAX_NUM_SAO_TYPE]; 567 m_iOffset[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 568 m_iOffsetOrg[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 605 m_iDist[i] = new Int64 [MAX_NUM_SAO_TYPE]; 606 m_dCost[i] = new Double [MAX_NUM_SAO_TYPE]; 607 608 m_iCount [i] = new Int64 *[MAX_NUM_SAO_TYPE]; 609 m_iOffset[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 610 m_iOffsetOrg[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 569 611 570 612 for (Int j=0;j<MAX_NUM_SAO_TYPE;j++) 571 613 { 572 m_iCount [i][j] = new Int64 [MAX_NUM_SAO_CLASS]; 573 m_iOffset[i][j] = new Int64 [MAX_NUM_SAO_CLASS]; 574 m_iOffsetOrg[i][j]= new Int64 [MAX_NUM_SAO_CLASS]; 614 m_iCount [i][j] = new Int64 [MAX_NUM_SAO_CLASS]; 615 m_iOffset[i][j] = new Int64 [MAX_NUM_SAO_CLASS]; 616 m_iOffsetOrg[i][j]= new Int64 [MAX_NUM_SAO_CLASS]; 617 } 618 } 619 Int numLcu = m_iNumCuInWidth * m_iNumCuInHeight; 620 m_count_PreDblk = new Int64 ***[numLcu]; 621 m_offsetOrg_PreDblk = new Int64 ***[numLcu]; 622 for (Int i=0; i<numLcu; i++) 623 { 624 m_count_PreDblk[i] = new Int64 **[3]; 625 m_offsetOrg_PreDblk[i] = new Int64 **[3]; 626 627 for (Int j=0;j<3;j++) 628 { 629 m_count_PreDblk [i][j] = new Int64 *[MAX_NUM_SAO_TYPE]; 630 m_offsetOrg_PreDblk[i][j] = new Int64 *[MAX_NUM_SAO_TYPE]; 631 632 for (Int k=0;k<MAX_NUM_SAO_TYPE;k++) 633 { 634 m_count_PreDblk [i][j][k] = new Int64 [MAX_NUM_SAO_CLASS]; 635 m_offsetOrg_PreDblk[i][j][k]= new Int64 [MAX_NUM_SAO_CLASS]; 636 } 575 637 } 576 638 } … … 606 668 607 669 /** Start SAO encoder 608 * \param pcPic, pcEntropyCoder, pppcRDSbacCoder, pcRDGoOnSbacCoder 670 * \param pcPic, pcEntropyCoder, pppcRDSbacCoder, pcRDGoOnSbacCoder 609 671 */ 610 672 Void TEncSampleAdaptiveOffset::startSaoEnc( TComPic* pcPic, TEncEntropy* pcEntropyCoder, TEncSbac*** pppcRDSbacCoder, TEncSbac* pcRDGoOnSbacCoder) 611 673 { 612 if( pcRDGoOnSbacCoder ) 613 m_bUseSBACRD = true; 614 else 615 m_bUseSBACRD = false; 616 674 m_bUseSBACRD = true; 617 675 m_pcPic = pcPic; 618 676 m_pcEntropyCoder = pcEntropyCoder; 619 677 620 678 m_pcRDGoOnSbacCoder = pcRDGoOnSbacCoder; 679 m_pcEntropyCoder->setEntropyCoder(m_pcRDGoOnSbacCoder, pcPic->getSlice(0)); 621 680 m_pcEntropyCoder->resetEntropy(); 622 681 m_pcEntropyCoder->resetBits(); … … 672 731 if (classIdx) 673 732 { 674 stats[classIdx] += (pOrg[x] - pRec[x]); 733 stats[classIdx] += (pOrg[x] - pRec[x]); 675 734 count[classIdx] ++; 676 735 } … … 685 744 pRec = pRecStart; 686 745 687 688 746 startX = (pbBorderAvail[SGU_L]) ? 0 : 1; 689 747 endX = (pbBorderAvail[SGU_R]) ? width : (width -1); … … 693 751 for (x=startX; x< endX; x++) 694 752 { 695 signRight = xSign(pRec[x] - pRec[x+1]); 753 signRight = xSign(pRec[x] - pRec[x+1]); 696 754 edgeType = signRight + signLeft + 2; 697 755 signLeft = -signRight; … … 726 784 for (x=0; x< width; x++) 727 785 { 728 signDown = xSign(pRec[x] - pRec[x+stride]); 786 signDown = xSign(pRec[x] - pRec[x+stride]); 729 787 edgeType = signDown + m_iUpBuff1[x] + 2; 730 788 m_iUpBuff1[x] = -signDown; … … 785 843 count[m_auiEoTable[edgeType]] ++; 786 844 787 m_iUpBufft[x+1] = -signDown1; 845 m_iUpBufft[x+1] = -signDown1; 788 846 } 789 847 m_iUpBufft[startX] = xSign(pRec[stride+startX] - pRec[startX-1]); … … 931 989 posOffset = (yPos* stride) + xPos; 932 990 933 #if HHI_INTERVIEW_SKIP934 if( !m_pcPic->getCU(iAddr)->getRenderable(0 ))935 {936 991 calcSaoStatsBlock(pPicRec+ posOffset, pPicOrg+ posOffset, stride, ppStats, ppCount,width, height, pbBorderAvail); 937 } 938 #else 939 calcSaoStatsBlock(pPicRec+ posOffset, pPicOrg+ posOffset, stride, ppStats, ppCount,width, height, pbBorderAvail); 940 #endif 941 } 942 } 943 992 } 993 } 944 994 } 945 995 … … 974 1024 Int iIsChroma = (iYCbCr!=0)? 1:0; 975 1025 Int numSkipLine = iIsChroma? 2:4; 1026 if (m_saoLcuBasedOptimization == 0) 1027 { 1028 numSkipLine = 0; 1029 } 1030 1031 #if SAO_SKIP_RIGHT 1032 Int numSkipLineRight = iIsChroma? 3:5; 1033 if (m_saoLcuBasedOptimization == 0) 1034 { 1035 numSkipLineRight = 0; 1036 } 1037 #endif 1038 1039 iPicWidthTmp = m_iPicWidth >> iIsChroma; 1040 iPicHeightTmp = m_iPicHeight >> iIsChroma; 1041 iLcuWidth = iLcuWidth >> iIsChroma; 1042 iLcuHeight = iLcuHeight >> iIsChroma; 1043 uiLPelX = uiLPelX >> iIsChroma; 1044 uiTPelY = uiTPelY >> iIsChroma; 1045 uiRPelX = uiLPelX + iLcuWidth ; 1046 uiBPelY = uiTPelY + iLcuHeight ; 1047 uiRPelX = uiRPelX > iPicWidthTmp ? iPicWidthTmp : uiRPelX; 1048 uiBPelY = uiBPelY > iPicHeightTmp ? iPicHeightTmp : uiBPelY; 1049 iLcuWidth = uiRPelX - uiLPelX; 1050 iLcuHeight = uiBPelY - uiTPelY; 1051 1052 iStride = (iYCbCr == 0)? m_pcPic->getStride(): m_pcPic->getCStride(); 1053 1054 //if(iSaoType == BO_0 || iSaoType == BO_1) 1055 { 1056 if( m_saoLcuBasedOptimization && m_saoLcuBoundary ) 1057 { 1058 numSkipLine = iIsChroma? 1:3; 1059 numSkipLineRight = iIsChroma? 2:4; 1060 } 1061 iStats = m_iOffsetOrg[iPartIdx][SAO_BO]; 1062 iCount = m_iCount [iPartIdx][SAO_BO]; 1063 1064 pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr); 1065 pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr); 1066 1067 #if SAO_SKIP_RIGHT 1068 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth : iLcuWidth-numSkipLineRight; 1069 #endif 1070 1071 iEndY = (uiBPelY == iPicHeightTmp) ? iLcuHeight : iLcuHeight-numSkipLine; 1072 for (y=0; y<iEndY; y++) 1073 { 1074 #if SAO_SKIP_RIGHT 1075 for (x=0; x<iEndX; x++) 1076 #else 1077 for (x=0; x<iLcuWidth; x++) 1078 #endif 1079 { 1080 iClassIdx = m_lumaTableBo[pRec[x]]; 1081 if (iClassIdx) 1082 { 1083 iStats[iClassIdx] += (pOrg[x] - pRec[x]); 1084 iCount[iClassIdx] ++; 1085 } 1086 } 1087 pOrg += iStride; 1088 pRec += iStride; 1089 } 1090 1091 } 1092 Int iSignLeft; 1093 Int iSignRight; 1094 Int iSignDown; 1095 Int iSignDown1; 1096 Int iSignDown2; 1097 1098 UInt uiEdgeType; 1099 1100 //if (iSaoType == EO_0 || iSaoType == EO_1 || iSaoType == EO_2 || iSaoType == EO_3) 1101 { 1102 //if (iSaoType == EO_0) 1103 { 1104 if( m_saoLcuBasedOptimization && m_saoLcuBoundary ) 1105 { 1106 numSkipLine = iIsChroma? 1:3; 1107 numSkipLineRight = iIsChroma? 3:5; 1108 } 1109 iStats = m_iOffsetOrg[iPartIdx][SAO_EO_0]; 1110 iCount = m_iCount [iPartIdx][SAO_EO_0]; 1111 1112 pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr); 1113 pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr); 1114 1115 iStartX = (uiLPelX == 0) ? 1 : 0; 1116 #if SAO_SKIP_RIGHT 1117 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth-numSkipLineRight; 1118 #else 1119 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth; 1120 #endif 1121 for (y=0; y<iLcuHeight-numSkipLine; y++) 1122 { 1123 iSignLeft = xSign(pRec[iStartX] - pRec[iStartX-1]); 1124 for (x=iStartX; x< iEndX; x++) 1125 { 1126 iSignRight = xSign(pRec[x] - pRec[x+1]); 1127 uiEdgeType = iSignRight + iSignLeft + 2; 1128 iSignLeft = -iSignRight; 1129 1130 iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]); 1131 iCount[m_auiEoTable[uiEdgeType]] ++; 1132 } 1133 pOrg += iStride; 1134 pRec += iStride; 1135 } 1136 } 1137 1138 //if (iSaoType == EO_1) 1139 { 1140 if( m_saoLcuBasedOptimization && m_saoLcuBoundary ) 1141 { 1142 numSkipLine = iIsChroma? 2:4; 1143 numSkipLineRight = iIsChroma? 2:4; 1144 } 1145 iStats = m_iOffsetOrg[iPartIdx][SAO_EO_1]; 1146 iCount = m_iCount [iPartIdx][SAO_EO_1]; 1147 1148 pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr); 1149 pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr); 1150 1151 iStartY = (uiTPelY == 0) ? 1 : 0; 1152 #if SAO_SKIP_RIGHT 1153 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth : iLcuWidth-numSkipLineRight; 1154 #endif 1155 iEndY = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight-numSkipLine; 1156 if (uiTPelY == 0) 1157 { 1158 pOrg += iStride; 1159 pRec += iStride; 1160 } 1161 1162 for (x=0; x< iLcuWidth; x++) 1163 { 1164 m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-iStride]); 1165 } 1166 for (y=iStartY; y<iEndY; y++) 1167 { 1168 #if SAO_SKIP_RIGHT 1169 for (x=0; x<iEndX; x++) 1170 #else 1171 for (x=0; x<iLcuWidth; x++) 1172 #endif 1173 { 1174 iSignDown = xSign(pRec[x] - pRec[x+iStride]); 1175 uiEdgeType = iSignDown + m_iUpBuff1[x] + 2; 1176 m_iUpBuff1[x] = -iSignDown; 1177 1178 iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]); 1179 iCount[m_auiEoTable[uiEdgeType]] ++; 1180 } 1181 pOrg += iStride; 1182 pRec += iStride; 1183 } 1184 } 1185 //if (iSaoType == EO_2) 1186 { 1187 if( m_saoLcuBasedOptimization && m_saoLcuBoundary ) 1188 { 1189 numSkipLine = iIsChroma? 2:4; 1190 numSkipLineRight = iIsChroma? 3:5; 1191 } 1192 iStats = m_iOffsetOrg[iPartIdx][SAO_EO_2]; 1193 iCount = m_iCount [iPartIdx][SAO_EO_2]; 1194 1195 pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr); 1196 pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr); 1197 1198 iStartX = (uiLPelX == 0) ? 1 : 0; 1199 #if SAO_SKIP_RIGHT 1200 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth-numSkipLineRight; 1201 #else 1202 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth; 1203 #endif 1204 1205 iStartY = (uiTPelY == 0) ? 1 : 0; 1206 iEndY = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight-numSkipLine; 1207 if (uiTPelY == 0) 1208 { 1209 pOrg += iStride; 1210 pRec += iStride; 1211 } 1212 1213 for (x=iStartX; x<iEndX; x++) 1214 { 1215 m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-iStride-1]); 1216 } 1217 for (y=iStartY; y<iEndY; y++) 1218 { 1219 iSignDown2 = xSign(pRec[iStride+iStartX] - pRec[iStartX-1]); 1220 for (x=iStartX; x<iEndX; x++) 1221 { 1222 iSignDown1 = xSign(pRec[x] - pRec[x+iStride+1]) ; 1223 uiEdgeType = iSignDown1 + m_iUpBuff1[x] + 2; 1224 m_iUpBufft[x+1] = -iSignDown1; 1225 iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]); 1226 iCount[m_auiEoTable[uiEdgeType]] ++; 1227 } 1228 m_iUpBufft[iStartX] = iSignDown2; 1229 ipSwap = m_iUpBuff1; 1230 m_iUpBuff1 = m_iUpBufft; 1231 m_iUpBufft = ipSwap; 1232 1233 pRec += iStride; 1234 pOrg += iStride; 1235 } 1236 } 1237 //if (iSaoType == EO_3 ) 1238 { 1239 if( m_saoLcuBasedOptimization && m_saoLcuBoundary ) 1240 { 1241 numSkipLine = iIsChroma? 2:4; 1242 numSkipLineRight = iIsChroma? 3:5; 1243 } 1244 iStats = m_iOffsetOrg[iPartIdx][SAO_EO_3]; 1245 iCount = m_iCount [iPartIdx][SAO_EO_3]; 1246 1247 pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr); 1248 pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr); 1249 1250 iStartX = (uiLPelX == 0) ? 1 : 0; 1251 #if SAO_SKIP_RIGHT 1252 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth-numSkipLineRight; 1253 #else 1254 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth; 1255 #endif 1256 1257 iStartY = (uiTPelY == 0) ? 1 : 0; 1258 iEndY = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight-numSkipLine; 1259 if (iStartY == 1) 1260 { 1261 pOrg += iStride; 1262 pRec += iStride; 1263 } 1264 1265 for (x=iStartX-1; x<iEndX; x++) 1266 { 1267 m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-iStride+1]); 1268 } 1269 1270 for (y=iStartY; y<iEndY; y++) 1271 { 1272 for (x=iStartX; x<iEndX; x++) 1273 { 1274 iSignDown1 = xSign(pRec[x] - pRec[x+iStride-1]) ; 1275 uiEdgeType = iSignDown1 + m_iUpBuff1[x] + 2; 1276 m_iUpBuff1[x-1] = -iSignDown1; 1277 iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]); 1278 iCount[m_auiEoTable[uiEdgeType]] ++; 1279 } 1280 m_iUpBuff1[iEndX-1] = xSign(pRec[iEndX-1 + iStride] - pRec[iEndX]); 1281 1282 pRec += iStride; 1283 pOrg += iStride; 1284 } 1285 } 1286 } 1287 } 1288 1289 1290 Void TEncSampleAdaptiveOffset::calcSaoStatsCu_BeforeDblk( TComPic* pcPic ) 1291 { 1292 Int addr, yCbCr; 1293 Int x,y; 1294 TComSPS *pTmpSPS = pcPic->getSlice(0)->getSPS(); 1295 1296 Pel* pOrg; 1297 Pel* pRec; 1298 Int stride; 1299 Int lcuWidth = pTmpSPS->getMaxCUHeight(); 1300 Int lcuHeight = pTmpSPS->getMaxCUWidth(); 1301 UInt rPelX; 1302 UInt bPelY; 1303 Int64* stats; 1304 Int64* count; 1305 Int classIdx; 1306 Int picWidthTmp = 0; 1307 Int picHeightTmp = 0; 1308 Int startX; 1309 Int startY; 1310 Int endX; 1311 Int endY; 1312 Int firstX, firstY; 1313 1314 Int idxY; 1315 Int idxX; 1316 Int frameHeightInCU = m_iNumCuInHeight; 1317 Int frameWidthInCU = m_iNumCuInWidth; 1318 Int j, k; 1319 1320 Int isChroma; 1321 Int numSkipLine, numSkipLineRight; 1322 1323 UInt lPelX, tPelY; 1324 TComDataCU *pTmpCu; 1325 1326 for (idxY = 0; idxY< frameHeightInCU; idxY++) 1327 { 1328 for (idxX = 0; idxX< frameWidthInCU; idxX++) 1329 { 1330 lcuWidth = pTmpSPS->getMaxCUHeight(); 1331 lcuHeight = pTmpSPS->getMaxCUWidth(); 1332 addr = idxX + frameWidthInCU*idxY; 1333 pTmpCu = pcPic->getCU(addr); 1334 lPelX = pTmpCu->getCUPelX(); 1335 tPelY = pTmpCu->getCUPelY(); 1336 for( yCbCr = 0; yCbCr < 3; yCbCr++ ) 1337 { 1338 isChroma = (yCbCr!=0)? 1:0; 1339 1340 for ( j=0;j<MAX_NUM_SAO_TYPE;j++) 1341 { 1342 for ( k=0;k< MAX_NUM_SAO_CLASS;k++) 1343 { 1344 m_count_PreDblk [addr][yCbCr][j][k] = 0; 1345 m_offsetOrg_PreDblk[addr][yCbCr][j][k] = 0; 1346 } 1347 } 1348 if( yCbCr == 0 ) 1349 { 1350 picWidthTmp = m_iPicWidth; 1351 picHeightTmp = m_iPicHeight; 1352 } 1353 else if( yCbCr == 1 ) 1354 { 1355 picWidthTmp = m_iPicWidth >> isChroma; 1356 picHeightTmp = m_iPicHeight >> isChroma; 1357 lcuWidth = lcuWidth >> isChroma; 1358 lcuHeight = lcuHeight >> isChroma; 1359 lPelX = lPelX >> isChroma; 1360 tPelY = tPelY >> isChroma; 1361 } 1362 rPelX = lPelX + lcuWidth ; 1363 bPelY = tPelY + lcuHeight ; 1364 rPelX = rPelX > picWidthTmp ? picWidthTmp : rPelX; 1365 bPelY = bPelY > picHeightTmp ? picHeightTmp : bPelY; 1366 lcuWidth = rPelX - lPelX; 1367 lcuHeight = bPelY - tPelY; 1368 1369 stride = (yCbCr == 0)? pcPic->getStride(): pcPic->getCStride(); 1370 1371 //if(iSaoType == BO) 1372 1373 numSkipLine = isChroma? 1:3; 1374 numSkipLineRight = isChroma? 2:4; 1375 1376 stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_BO]; 1377 count = m_count_PreDblk[addr][yCbCr][SAO_BO]; 1378 1379 pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr); 1380 pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr); 1381 1382 startX = (rPelX == picWidthTmp) ? lcuWidth : lcuWidth-numSkipLineRight; 1383 startY = (bPelY == picHeightTmp) ? lcuHeight : lcuHeight-numSkipLine; 1384 1385 for (y=0; y<lcuHeight; y++) 1386 { 1387 for (x=0; x<lcuWidth; x++) 1388 { 1389 if( x < startX && y < startY ) 1390 continue; 1391 1392 classIdx = m_lumaTableBo[pRec[x]]; 1393 if (classIdx) 1394 { 1395 stats[classIdx] += (pOrg[x] - pRec[x]); 1396 count[classIdx] ++; 1397 } 1398 } 1399 pOrg += stride; 1400 pRec += stride; 1401 } 1402 1403 Int signLeft; 1404 Int signRight; 1405 Int signDown; 1406 Int signDown1; 1407 Int signDown2; 1408 1409 UInt uiEdgeType; 1410 1411 //if (iSaoType == EO_0) 1412 1413 numSkipLine = isChroma? 1:3; 1414 numSkipLineRight = isChroma? 3:5; 1415 1416 stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_EO_0]; 1417 count = m_count_PreDblk[addr][yCbCr][SAO_EO_0]; 1418 1419 pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr); 1420 pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr); 1421 1422 startX = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth-numSkipLineRight; 1423 startY = (bPelY == picHeightTmp) ? lcuHeight : lcuHeight-numSkipLine; 1424 firstX = (lPelX == 0) ? 1 : 0; 1425 endX = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth; 1426 1427 for (y=0; y<lcuHeight; y++) 1428 { 1429 signLeft = xSign(pRec[firstX] - pRec[firstX-1]); 1430 for (x=firstX; x< endX; x++) 1431 { 1432 signRight = xSign(pRec[x] - pRec[x+1]); 1433 uiEdgeType = signRight + signLeft + 2; 1434 signLeft = -signRight; 1435 1436 if( x < startX && y < startY ) 1437 continue; 1438 1439 stats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]); 1440 count[m_auiEoTable[uiEdgeType]] ++; 1441 } 1442 pOrg += stride; 1443 pRec += stride; 1444 } 1445 1446 //if (iSaoType == EO_1) 1447 1448 numSkipLine = isChroma? 2:4; 1449 numSkipLineRight = isChroma? 2:4; 1450 1451 stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_EO_1]; 1452 count = m_count_PreDblk[addr][yCbCr][SAO_EO_1]; 1453 1454 pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr); 1455 pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr); 1456 1457 startX = (rPelX == picWidthTmp) ? lcuWidth : lcuWidth-numSkipLineRight; 1458 startY = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight-numSkipLine; 1459 firstY = (tPelY == 0) ? 1 : 0; 1460 endY = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight; 1461 if (firstY == 1) 1462 { 1463 pOrg += stride; 1464 pRec += stride; 1465 } 1466 1467 for (x=0; x< lcuWidth; x++) 1468 { 1469 m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-stride]); 1470 } 1471 for (y=firstY; y<endY; y++) 1472 { 1473 for (x=0; x<lcuWidth; x++) 1474 { 1475 signDown = xSign(pRec[x] - pRec[x+stride]); 1476 uiEdgeType = signDown + m_iUpBuff1[x] + 2; 1477 m_iUpBuff1[x] = -signDown; 1478 1479 if( x < startX && y < startY ) 1480 continue; 1481 1482 stats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]); 1483 count[m_auiEoTable[uiEdgeType]] ++; 1484 } 1485 pOrg += stride; 1486 pRec += stride; 1487 } 1488 1489 //if (iSaoType == EO_2) 1490 1491 numSkipLine = isChroma? 2:4; 1492 numSkipLineRight = isChroma? 3:5; 1493 1494 stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_EO_2]; 1495 count = m_count_PreDblk[addr][yCbCr][SAO_EO_2]; 1496 1497 pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr); 1498 pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr); 1499 1500 startX = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth-numSkipLineRight; 1501 startY = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight-numSkipLine; 1502 firstX = (lPelX == 0) ? 1 : 0; 1503 firstY = (tPelY == 0) ? 1 : 0; 1504 endX = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth; 1505 endY = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight; 1506 if (firstY == 1) 1507 { 1508 pOrg += stride; 1509 pRec += stride; 1510 } 1511 1512 for (x=firstX; x<endX; x++) 1513 { 1514 m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-stride-1]); 1515 } 1516 for (y=firstY; y<endY; y++) 1517 { 1518 signDown2 = xSign(pRec[stride+startX] - pRec[startX-1]); 1519 for (x=firstX; x<endX; x++) 1520 { 1521 signDown1 = xSign(pRec[x] - pRec[x+stride+1]) ; 1522 uiEdgeType = signDown1 + m_iUpBuff1[x] + 2; 1523 m_iUpBufft[x+1] = -signDown1; 1524 1525 if( x < startX && y < startY ) 1526 continue; 1527 1528 stats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]); 1529 count[m_auiEoTable[uiEdgeType]] ++; 1530 } 1531 m_iUpBufft[firstX] = signDown2; 1532 ipSwap = m_iUpBuff1; 1533 m_iUpBuff1 = m_iUpBufft; 1534 m_iUpBufft = ipSwap; 1535 1536 pRec += stride; 1537 pOrg += stride; 1538 } 1539 1540 //if (iSaoType == EO_3) 1541 1542 numSkipLine = isChroma? 2:4; 1543 numSkipLineRight = isChroma? 3:5; 1544 1545 stats = m_offsetOrg_PreDblk[addr][yCbCr][SAO_EO_3]; 1546 count = m_count_PreDblk[addr][yCbCr][SAO_EO_3]; 1547 1548 pOrg = getPicYuvAddr(pcPic->getPicYuvOrg(), yCbCr, addr); 1549 pRec = getPicYuvAddr(pcPic->getPicYuvRec(), yCbCr, addr); 1550 1551 startX = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth-numSkipLineRight; 1552 startY = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight-numSkipLine; 1553 firstX = (lPelX == 0) ? 1 : 0; 1554 firstY = (tPelY == 0) ? 1 : 0; 1555 endX = (rPelX == picWidthTmp) ? lcuWidth-1 : lcuWidth; 1556 endY = (bPelY == picHeightTmp) ? lcuHeight-1 : lcuHeight; 1557 if (firstY == 1) 1558 { 1559 pOrg += stride; 1560 pRec += stride; 1561 } 1562 1563 for (x=firstX-1; x<endX; x++) 1564 { 1565 m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-stride+1]); 1566 } 1567 1568 for (y=firstY; y<endY; y++) 1569 { 1570 for (x=firstX; x<endX; x++) 1571 { 1572 signDown1 = xSign(pRec[x] - pRec[x+stride-1]) ; 1573 uiEdgeType = signDown1 + m_iUpBuff1[x] + 2; 1574 m_iUpBuff1[x-1] = -signDown1; 1575 1576 if( x < startX && y < startY ) 1577 continue; 1578 1579 stats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]); 1580 count[m_auiEoTable[uiEdgeType]] ++; 1581 } 1582 m_iUpBuff1[endX-1] = xSign(pRec[endX-1 + stride] - pRec[endX]); 1583 1584 pRec += stride; 1585 pOrg += stride; 1586 } 1587 } 1588 } 1589 } 1590 } 1591 1592 1593 /** get SAO statistics 1594 * \param *psQTPart, iYCbCr 1595 */ 1596 Void TEncSampleAdaptiveOffset::getSaoStats(SAOQTPart *psQTPart, Int iYCbCr) 1597 { 1598 Int iLevelIdx, iPartIdx, iTypeIdx, iClassIdx; 1599 Int i; 1600 Int iNumTotalType = MAX_NUM_SAO_TYPE; 1601 Int LcuIdxX; 1602 Int LcuIdxY; 1603 Int iAddr; 1604 Int iFrameWidthInCU = m_pcPic->getFrameWidthInCU(); 1605 Int iDownPartIdx; 1606 Int iPartStart; 1607 Int iPartEnd; 1608 SAOQTPart* pOnePart; 1609 1610 if (m_uiMaxSplitLevel == 0) 1611 { 1612 iPartIdx = 0; 1613 pOnePart = &(psQTPart[iPartIdx]); 1614 for (LcuIdxY = pOnePart->StartCUY; LcuIdxY<= pOnePart->EndCUY; LcuIdxY++) 1615 { 1616 for (LcuIdxX = pOnePart->StartCUX; LcuIdxX<= pOnePart->EndCUX; LcuIdxX++) 1617 { 1618 iAddr = LcuIdxY*iFrameWidthInCU + LcuIdxX; 1619 calcSaoStatsCu(iAddr, iPartIdx, iYCbCr); 1620 } 1621 } 1622 } 1623 else 1624 { 1625 for(iPartIdx=m_aiNumCulPartsLevel[m_uiMaxSplitLevel-1]; iPartIdx<m_aiNumCulPartsLevel[m_uiMaxSplitLevel]; iPartIdx++) 1626 { 1627 pOnePart = &(psQTPart[iPartIdx]); 1628 for (LcuIdxY = pOnePart->StartCUY; LcuIdxY<= pOnePart->EndCUY; LcuIdxY++) 1629 { 1630 for (LcuIdxX = pOnePart->StartCUX; LcuIdxX<= pOnePart->EndCUX; LcuIdxX++) 1631 { 1632 iAddr = LcuIdxY*iFrameWidthInCU + LcuIdxX; 1633 calcSaoStatsCu(iAddr, iPartIdx, iYCbCr); 1634 } 1635 } 1636 } 1637 for (iLevelIdx = m_uiMaxSplitLevel-1; iLevelIdx>=0; iLevelIdx-- ) 1638 { 1639 iPartStart = (iLevelIdx > 0) ? m_aiNumCulPartsLevel[iLevelIdx-1] : 0; 1640 iPartEnd = m_aiNumCulPartsLevel[iLevelIdx]; 1641 1642 for(iPartIdx = iPartStart; iPartIdx < iPartEnd; iPartIdx++) 1643 { 1644 pOnePart = &(psQTPart[iPartIdx]); 1645 for (i=0; i< NUM_DOWN_PART; i++) 1646 { 1647 iDownPartIdx = pOnePart->DownPartsIdx[i]; 1648 for (iTypeIdx=0; iTypeIdx<iNumTotalType; iTypeIdx++) 1649 { 1650 for (iClassIdx=0; iClassIdx< (iTypeIdx < SAO_BO ? m_iNumClass[iTypeIdx] : SAO_MAX_BO_CLASSES) +1; iClassIdx++) 1651 { 1652 m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx] += m_iOffsetOrg[iDownPartIdx][iTypeIdx][iClassIdx]; 1653 m_iCount [iPartIdx][iTypeIdx][iClassIdx] += m_iCount [iDownPartIdx][iTypeIdx][iClassIdx]; 1654 } 1655 } 1656 } 1657 } 1658 } 1659 } 1660 } 1661 1662 /** reset offset statistics 1663 * \param 1664 */ 1665 Void TEncSampleAdaptiveOffset::resetStats() 1666 { 1667 for (Int i=0;i<m_iNumTotalParts;i++) 1668 { 1669 m_dCostPartBest[i] = MAX_DOUBLE; 1670 m_iTypePartBest[i] = -1; 1671 m_iDistOrg[i] = 0; 1672 for (Int j=0;j<MAX_NUM_SAO_TYPE;j++) 1673 { 1674 m_iDist[i][j] = 0; 1675 m_iRate[i][j] = 0; 1676 m_dCost[i][j] = 0; 1677 for (Int k=0;k<MAX_NUM_SAO_CLASS;k++) 1678 { 1679 m_iCount [i][j][k] = 0; 1680 m_iOffset[i][j][k] = 0; 1681 m_iOffsetOrg[i][j][k] = 0; 1682 } 1683 } 1684 } 1685 } 1686 1687 #if SAO_CHROMA_LAMBDA 1688 /** Sample adaptive offset process 1689 * \param pcSaoParam 1690 * \param dLambdaLuma 1691 * \param dLambdaChroma 1692 */ 1693 #if SAO_ENCODING_CHOICE 1694 Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, Double dLambdaLuma, Double dLambdaChroma, Int depth) 1695 #else 1696 Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, Double dLambdaLuma, Double dLambdaChroma) 1697 #endif 1698 #else 1699 /** Sample adaptive offset process 1700 * \param dLambda 1701 */ 1702 Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, Double dLambda) 1703 #endif 1704 { 1705 m_eSliceType = m_pcPic->getSlice(0)->getSliceType(); 1706 m_iPicNalReferenceIdc = (m_pcPic->getSlice(0)->isReferenced() ? 1 :0); 1707 1708 #if SAO_CHROMA_LAMBDA 1709 m_dLambdaLuma = dLambdaLuma; 1710 m_dLambdaChroma = dLambdaChroma; 1711 #else 1712 m_dLambdaLuma = dLambda; 1713 m_dLambdaChroma = dLambda; 1714 #endif 1715 1716 if(m_bUseNIF) 1717 { 1718 m_pcPic->getPicYuvRec()->copyToPic(m_pcYuvTmp); 1719 } 1720 1721 #if FULL_NBIT 1722 m_uiSaoBitIncrease = g_uiBitDepth + (g_uiBitDepth-8) - min((Int)(g_uiBitDepth + (g_uiBitDepth-8)), 10); 1723 #else 1724 m_uiSaoBitIncrease = g_uiBitDepth + g_uiBitIncrement - min((Int)(g_uiBitDepth + g_uiBitIncrement), 10); 1725 #endif 1726 1727 #if FULL_NBIT 1728 m_iOffsetTh = 1 << ( min((Int)(g_uiBitDepth + (g_uiBitDepth-8)-5),5) ); 1729 #else 1730 m_iOffsetTh = 1 << ( min((Int)(g_uiBitDepth + g_uiBitIncrement-5),5) ); 1731 #endif 1732 1733 resetSAOParam(pcSaoParam); 1734 if( !m_saoLcuBasedOptimization || !m_saoLcuBoundary ) 1735 { 1736 resetStats(); 1737 } 1738 Double dCostFinal = 0; 1739 if ( m_saoLcuBasedOptimization) 1740 { 1741 #if SAO_ENCODING_CHOICE 1742 rdoSaoUnitAll(pcSaoParam, dLambdaLuma, dLambdaChroma, depth); 1743 #else 1744 rdoSaoUnitAll(pcSaoParam, dLambdaLuma, dLambdaChroma); 1745 #endif 1746 } 1747 else 1748 { 1749 pcSaoParam->bSaoFlag[0] = 1; 1750 pcSaoParam->bSaoFlag[1] = 0; 1751 dCostFinal = 0; 1752 Double lambdaRdo = dLambdaLuma; 1753 resetStats(); 1754 getSaoStats(pcSaoParam->psSaoPart[0], 0); 1755 runQuadTreeDecision(pcSaoParam->psSaoPart[0], 0, dCostFinal, m_uiMaxSplitLevel, lambdaRdo, 0); 1756 pcSaoParam->bSaoFlag[0] = dCostFinal < 0 ? 1:0; 1757 if(pcSaoParam->bSaoFlag[0]) 1758 { 1759 convertQT2SaoUnit(pcSaoParam, 0, 0); 1760 assignSaoUnitSyntax(pcSaoParam->saoLcuParam[0], pcSaoParam->psSaoPart[0], pcSaoParam->oneUnitFlag[0], 0); 1761 } 1762 } 1763 1764 if (pcSaoParam->bSaoFlag[0]) 1765 { 1766 processSaoUnitAll( pcSaoParam->saoLcuParam[0], pcSaoParam->oneUnitFlag[0], 0); 1767 } 1768 if (pcSaoParam->bSaoFlag[1]) 1769 { 1770 processSaoUnitAll( pcSaoParam->saoLcuParam[1], pcSaoParam->oneUnitFlag[1], 1); 1771 processSaoUnitAll( pcSaoParam->saoLcuParam[2], pcSaoParam->oneUnitFlag[2], 2); 1772 } 1773 } 1774 /** Check merge SAO unit 1775 * \param saoUnitCurr current SAO unit 1776 * \param saoUnitCheck SAO unit tobe check 1777 * \param dir direction 1778 */ 1779 Void TEncSampleAdaptiveOffset::checkMerge(SaoLcuParam * saoUnitCurr, SaoLcuParam * saoUnitCheck, Int dir) 1780 { 1781 Int i ; 1782 Int countDiff = 0; 1783 if (saoUnitCurr->partIdx != saoUnitCheck->partIdx) 1784 { 1785 if (saoUnitCurr->typeIdx !=-1) 1786 { 1787 if (saoUnitCurr->typeIdx == saoUnitCheck->typeIdx) 1788 { 1789 for (i=0;i<saoUnitCurr->length;i++) 1790 { 1791 countDiff += (saoUnitCurr->offset[i] != saoUnitCheck->offset[i]); 1792 } 1793 countDiff += (saoUnitCurr->subTypeIdx != saoUnitCheck->subTypeIdx); 1794 if (countDiff ==0) 1795 { 1796 saoUnitCurr->partIdx = saoUnitCheck->partIdx; 1797 if (dir == 1) 1798 { 1799 saoUnitCurr->mergeUpFlag = 1; 1800 saoUnitCurr->mergeLeftFlag = 0; 1801 } 1802 else 1803 { 1804 saoUnitCurr->mergeUpFlag = 0; 1805 saoUnitCurr->mergeLeftFlag = 1; 1806 } 1807 } 1808 } 1809 } 1810 else 1811 { 1812 if (saoUnitCurr->typeIdx == saoUnitCheck->typeIdx) 1813 { 1814 saoUnitCurr->partIdx = saoUnitCheck->partIdx; 1815 if (dir == 1) 1816 { 1817 saoUnitCurr->mergeUpFlag = 1; 1818 saoUnitCurr->mergeLeftFlag = 0; 1819 } 1820 else 1821 { 1822 saoUnitCurr->mergeUpFlag = 0; 1823 saoUnitCurr->mergeLeftFlag = 1; 1824 } 1825 } 1826 } 1827 } 1828 } 1829 /** Assign SAO unit syntax from picture-based algorithm 1830 * \param saoLcuParam SAO LCU parameters 1831 * \param saoPart SAO part 1832 * \param oneUnitFlag SAO one unit flag 1833 * \param iYCbCr color component Index 1834 */ 1835 Void TEncSampleAdaptiveOffset::assignSaoUnitSyntax(SaoLcuParam* saoLcuParam, SAOQTPart* saoPart, Bool &oneUnitFlag, Int yCbCr) 1836 { 1837 if (saoPart->bSplit == 0) 1838 { 1839 oneUnitFlag = 1; 1840 } 1841 else 1842 { 1843 Int i,j, addr, addrUp, addrLeft, idx, idxUp, idxLeft, idxCount; 1844 1845 oneUnitFlag = 0; 1846 1847 idxCount = -1; 1848 saoLcuParam[0].mergeUpFlag = 0; 1849 saoLcuParam[0].mergeLeftFlag = 0; 1850 1851 for (j=0;j<m_iNumCuInHeight;j++) 1852 { 1853 for (i=0;i<m_iNumCuInWidth;i++) 1854 { 1855 addr = i + j*m_iNumCuInWidth; 1856 addrLeft = (addr%m_iNumCuInWidth == 0) ? -1 : addr - 1; 1857 addrUp = (addr<m_iNumCuInWidth) ? -1 : addr - m_iNumCuInWidth; 1858 idx = saoLcuParam[addr].partIdxTmp; 1859 idxLeft = (addrLeft == -1) ? -1 : saoLcuParam[addrLeft].partIdxTmp; 1860 idxUp = (addrUp == -1) ? -1 : saoLcuParam[addrUp].partIdxTmp; 1861 1862 if(idx!=idxLeft && idx!=idxUp) 1863 { 1864 saoLcuParam[addr].mergeUpFlag = 0; idxCount++; 1865 saoLcuParam[addr].mergeLeftFlag = 0; 1866 saoLcuParam[addr].partIdx = idxCount; 1867 } 1868 else if (idx==idxLeft) 1869 { 1870 saoLcuParam[addr].mergeUpFlag = 1; 1871 saoLcuParam[addr].mergeLeftFlag = 1; 1872 saoLcuParam[addr].partIdx = saoLcuParam[addrLeft].partIdx; 1873 } 1874 else if (idx==idxUp) 1875 { 1876 saoLcuParam[addr].mergeUpFlag = 1; 1877 saoLcuParam[addr].mergeLeftFlag = 0; 1878 saoLcuParam[addr].partIdx = saoLcuParam[addrUp].partIdx; 1879 } 1880 if (addrUp != -1) 1881 { 1882 checkMerge(&saoLcuParam[addr], &saoLcuParam[addrUp], 1); 1883 } 1884 if (addrLeft != -1) 1885 { 1886 checkMerge(&saoLcuParam[addr], &saoLcuParam[addrLeft], 0); 1887 } 1888 } 1889 } 1890 } 1891 } 1892 /** rate distortion optimization of all SAO units 1893 * \param saoParam SAO parameters 1894 * \param lambda 1895 * \param lambdaChroma 1896 */ 1897 #if SAO_ENCODING_CHOICE 1898 Void TEncSampleAdaptiveOffset::rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma, Int depth) 1899 #else 1900 Void TEncSampleAdaptiveOffset::rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma) 1901 #endif 1902 { 1903 Int idxY; 1904 Int idxX; 1905 Int frameHeightInCU = saoParam->numCuInHeight; 1906 Int frameWidthInCU = saoParam->numCuInWidth; 1907 Int j, k; 1908 Int addr = 0; 1909 Int addrUp = -1; 1910 Int addrLeft = -1; 1911 Int compIdx = 0; 1912 SaoLcuParam mergeSaoParam[3][2]; 1913 Double compDistortion[3]; 1914 1915 saoParam->bSaoFlag[0] = true; 1916 saoParam->bSaoFlag[1] = true; 1917 saoParam->oneUnitFlag[0] = false; 1918 saoParam->oneUnitFlag[1] = false; 1919 saoParam->oneUnitFlag[2] = false; 1920 1921 #if SAO_ENCODING_CHOICE 1922 #if SAO_ENCODING_CHOICE_CHROMA 1923 Int numNoSao[2]; 1924 numNoSao[0] = 0;// Luma 1925 numNoSao[1] = 0;// Chroma 1926 if( depth > 0 && m_depthSaoRate[0][depth-1] > SAO_ENCODING_RATE ) 1927 { 1928 saoParam->bSaoFlag[0] = false; 1929 } 1930 1931 if( depth > 0 && m_depthSaoRate[1][depth-1] > SAO_ENCODING_RATE_CHROMA ) 1932 { 1933 saoParam->bSaoFlag[1] = false; 1934 } 1935 #else 1936 Int numNoSao = 0; 1937 1938 if( depth > 0 && m_depth0SaoRate > SAO_ENCODING_RATE ) 1939 { 1940 saoParam->bSaoFlag[0] = false; 1941 saoParam->bSaoFlag[1] = false; 1942 } 1943 #endif 1944 #endif 1945 1946 for (idxY = 0; idxY< frameHeightInCU; idxY++) 1947 { 1948 for (idxX = 0; idxX< frameWidthInCU; idxX++) 1949 { 1950 addr = idxX + frameWidthInCU*idxY; 1951 addrUp = addr < frameWidthInCU ? -1:idxX + frameWidthInCU*(idxY-1); 1952 addrLeft = idxX == 0 ? -1:idxX-1 + frameWidthInCU*idxY; 1953 Int allowMergeLeft = 1; 1954 Int allowMergeUp = 1; 1955 UInt rate; 1956 Double bestCost, mergeCost; 1957 1958 if (idxX!=0) 1959 { 1960 // check tile id and slice id 1961 if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-1) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-1)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx())) 1962 { 1963 allowMergeLeft = 0; 1964 } 1965 } 1966 else 1967 { 1968 allowMergeLeft = 0; 1969 } 1970 if (idxY!=0) 1971 { 1972 if ( (m_pcPic->getPicSym()->getTileIdxMap(addr-m_iNumCuInWidth) != m_pcPic->getPicSym()->getTileIdxMap(addr)) || (m_pcPic->getCU(addr-m_iNumCuInWidth)->getSlice()->getSliceIdx() != m_pcPic->getCU(addr)->getSlice()->getSliceIdx())) 1973 { 1974 allowMergeUp = 0; 1975 } 1976 } 1977 else 1978 { 1979 allowMergeUp = 0; 1980 } 1981 1982 compDistortion[0] = 0; 1983 compDistortion[1] = 0; 1984 compDistortion[2] = 0; 1985 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]); 1986 1987 if (allowMergeLeft) 1988 { 1989 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0); 1990 } 1991 if (allowMergeUp) 1992 { 1993 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0); 1994 } 1995 1996 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[0][CI_TEMP_BEST] ); 1997 1998 // reset stats Y, Cb, Cr 1999 for ( compIdx=0;compIdx<3;compIdx++) 2000 { 2001 for ( j=0;j<MAX_NUM_SAO_TYPE;j++) 2002 { 2003 for ( k=0;k< MAX_NUM_SAO_CLASS;k++) 2004 { 2005 m_iOffset [compIdx][j][k] = 0; 2006 if( m_saoLcuBasedOptimization && m_saoLcuBoundary ) 2007 { 2008 m_iCount [compIdx][j][k] = m_count_PreDblk [addr][compIdx][j][k]; 2009 m_iOffsetOrg[compIdx][j][k] = m_offsetOrg_PreDblk[addr][compIdx][j][k]; 2010 } 2011 else 2012 { 2013 m_iCount [compIdx][j][k] = 0; 2014 m_iOffsetOrg[compIdx][j][k] = 0; 2015 } 2016 } 2017 } 2018 saoParam->saoLcuParam[compIdx][addr].typeIdx = -1; 2019 saoParam->saoLcuParam[compIdx][addr].mergeUpFlag = 0; 2020 saoParam->saoLcuParam[compIdx][addr].mergeLeftFlag = 0; 2021 saoParam->saoLcuParam[compIdx][addr].subTypeIdx = 0; 2022 #if SAO_ENCODING_CHOICE 2023 if( (compIdx ==0 && saoParam->bSaoFlag[0])|| (compIdx >0 && saoParam->bSaoFlag[1]) ) 2024 #endif 2025 { 2026 calcSaoStatsCu(addr, compIdx, compIdx); 2027 } 2028 } 2029 saoComponentParamDist(allowMergeLeft, allowMergeUp, saoParam, addr, addrUp, addrLeft, 0, lambda, &mergeSaoParam[0][0], &compDistortion[0]); 2030 sao2ChromaParamDist(allowMergeLeft, allowMergeUp, saoParam, addr, addrUp, addrLeft, lambdaChroma, &mergeSaoParam[1][0], &mergeSaoParam[2][0], &compDistortion[0]); 2031 if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] ) 2032 { 2033 // Cost of new SAO_params 2034 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]); 2035 m_pcRDGoOnSbacCoder->resetBits(); 2036 if (allowMergeLeft) 2037 { 2038 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0); 2039 } 2040 if (allowMergeUp) 2041 { 2042 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(0); 2043 } 2044 for ( compIdx=0;compIdx<3;compIdx++) 2045 { 2046 if( (compIdx ==0 && saoParam->bSaoFlag[0]) || (compIdx >0 && saoParam->bSaoFlag[1])) 2047 { 2048 m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx); 2049 } 2050 } 2051 2052 rate = m_pcEntropyCoder->getNumberOfWrittenBits(); 2053 bestCost = compDistortion[0] + (Double)rate; 2054 m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[0][CI_TEMP_BEST]); 2055 2056 // Cost of Merge 2057 for(Int mergeUp=0; mergeUp<2; ++mergeUp) 2058 { 2059 if ( (allowMergeLeft && (mergeUp==0)) || (allowMergeUp && (mergeUp==1)) ) 2060 { 2061 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]); 2062 m_pcRDGoOnSbacCoder->resetBits(); 2063 if (allowMergeLeft) 2064 { 2065 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(1-mergeUp); 2066 } 2067 if ( allowMergeUp && (mergeUp==1) ) 2068 { 2069 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(1); 2070 } 2071 2072 rate = m_pcEntropyCoder->getNumberOfWrittenBits(); 2073 mergeCost = compDistortion[mergeUp+1] + (Double)rate; 2074 if (mergeCost < bestCost) 2075 { 2076 bestCost = mergeCost; 2077 m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[0][CI_TEMP_BEST]); 2078 for ( compIdx=0;compIdx<3;compIdx++) 2079 { 2080 mergeSaoParam[compIdx][mergeUp].mergeLeftFlag = 1-mergeUp; 2081 mergeSaoParam[compIdx][mergeUp].mergeUpFlag = mergeUp; 2082 if( (compIdx==0 && saoParam->bSaoFlag[0]) || (compIdx>0 && saoParam->bSaoFlag[1])) 2083 { 2084 copySaoUnit(&saoParam->saoLcuParam[compIdx][addr], &mergeSaoParam[compIdx][mergeUp] ); 2085 } 2086 } 2087 } 2088 } 2089 } 2090 #if SAO_ENCODING_CHOICE 2091 #if SAO_ENCODING_CHOICE_CHROMA 2092 if( saoParam->saoLcuParam[0][addr].typeIdx == -1) 2093 { 2094 numNoSao[0]++; 2095 } 2096 if( saoParam->saoLcuParam[1][addr].typeIdx == -1) 2097 { 2098 numNoSao[1]+=2; 2099 } 2100 #else 2101 for ( compIdx=0;compIdx<3;compIdx++) 2102 { 2103 if( depth == 0 && saoParam->saoLcuParam[compIdx][addr].typeIdx == -1) 2104 { 2105 numNoSao++; 2106 } 2107 } 2108 #endif 2109 #endif 2110 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]); 2111 m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[0][CI_CURR_BEST]); 2112 } 2113 } 2114 } 2115 #if SAO_ENCODING_CHOICE 2116 #if SAO_ENCODING_CHOICE_CHROMA 2117 #if SAO_ENCODING_CHOICE_CHROMA_BF 2118 if( !saoParam->bSaoFlag[0]) 2119 { 2120 m_depthSaoRate[0][depth] = 1.0; 2121 } 2122 else 2123 { 2124 m_depthSaoRate[0][depth] = numNoSao[0]/((Double) frameHeightInCU*frameWidthInCU); 2125 } 2126 if( !saoParam->bSaoFlag[1]) 2127 { 2128 m_depthSaoRate[1][depth] = 1.0; 2129 } 2130 else 2131 { 2132 m_depthSaoRate[1][depth] = numNoSao[1]/((Double) frameHeightInCU*frameWidthInCU*2); 2133 } 2134 #else 2135 m_depthSaoRate[0][depth] = numNoSao[0]/((Double) frameHeightInCU*frameWidthInCU); 2136 m_depthSaoRate[1][depth] = numNoSao[1]/((Double) frameHeightInCU*frameWidthInCU*2); 2137 #endif 2138 #else 2139 if( depth == 0) 2140 { 2141 // update SAO Rate 2142 m_depth0SaoRate = numNoSao/((Double) frameHeightInCU*frameWidthInCU*3); 2143 } 2144 #endif 2145 #endif 2146 } 2147 /** rate distortion optimization of SAO unit 2148 * \param saoParam SAO parameters 2149 * \param addr address 2150 * \param addrUp above address 2151 * \param addrLeft left address 2152 * \param yCbCr color component index 2153 * \param lambda 2154 */ 2155 inline Int64 TEncSampleAdaptiveOffset::estSaoTypeDist(Int compIdx, Int typeIdx, Int shift, Double lambda, Int *currentDistortionTableBo, Double *currentRdCostTableBo) 2156 { 2157 Int64 estDist = 0; 2158 Int classIdx; 2159 for(classIdx=1; classIdx < ( (typeIdx < SAO_BO) ? m_iNumClass[typeIdx]+1 : SAO_MAX_BO_CLASSES+1); classIdx++) 2160 { 2161 if( typeIdx == SAO_BO) 2162 { 2163 currentDistortionTableBo[classIdx-1] = 0; 2164 currentRdCostTableBo[classIdx-1] = lambda; 2165 } 2166 if(m_iCount [compIdx][typeIdx][classIdx]) 2167 { 2168 #if FULL_NBIT 2169 m_iOffset[compIdx][typeIdx][classIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[compIdx][typeIdx][classIdx]<<g_uiBitDepth-8) / (Double)(m_iCount [compIdx][typeIdx][classIdx]<<m_uiSaoBitIncrease)); 2170 #else 2171 m_iOffset[compIdx][typeIdx][classIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[compIdx][typeIdx][classIdx]<<g_uiBitIncrement) / (Double)(m_iCount [compIdx][typeIdx][classIdx]<<m_uiSaoBitIncrease)); 2172 #endif 2173 m_iOffset[compIdx][typeIdx][classIdx] = Clip3(-m_iOffsetTh+1, m_iOffsetTh-1, (Int)m_iOffset[compIdx][typeIdx][classIdx]); 2174 if (typeIdx < 4) 2175 { 2176 if ( m_iOffset[compIdx][typeIdx][classIdx]<0 && classIdx<3 ) 2177 { 2178 m_iOffset[compIdx][typeIdx][classIdx] = 0; 2179 } 2180 if ( m_iOffset[compIdx][typeIdx][classIdx]>0 && classIdx>=3) 2181 { 2182 m_iOffset[compIdx][typeIdx][classIdx] = 0; 2183 } 2184 } 2185 m_iOffset[compIdx][typeIdx][classIdx] = estIterOffset( typeIdx, classIdx, lambda, m_iOffset[compIdx][typeIdx][classIdx], m_iCount [compIdx][typeIdx][classIdx], m_iOffsetOrg[compIdx][typeIdx][classIdx], shift, m_uiSaoBitIncrease, currentDistortionTableBo, currentRdCostTableBo ); 2186 } 2187 else 2188 { 2189 m_iOffsetOrg[compIdx][typeIdx][classIdx] = 0; 2190 m_iOffset[compIdx][typeIdx][classIdx] = 0; 2191 } 2192 if( typeIdx != SAO_BO ) 2193 { 2194 estDist += estSaoDist( m_iCount [compIdx][typeIdx][classIdx], m_iOffset[compIdx][typeIdx][classIdx] << m_uiSaoBitIncrease, m_iOffsetOrg[compIdx][typeIdx][classIdx], shift); 2195 } 2196 } 2197 return estDist; 2198 } 2199 2200 inline Int64 TEncSampleAdaptiveOffset::estSaoDist(Int64 count, Int64 offset, Int64 offsetOrg, Int shift) 2201 { 2202 return (( count*offset*offset-offsetOrg*offset*2 ) >> shift); 2203 } 2204 inline Int64 TEncSampleAdaptiveOffset::estIterOffset(Int typeIdx, Int classIdx, double lambda, Int64 offsetInput, Int64 count, Int64 offsetOrg, Int shift, Int bitIncrease, Int *currentDistortionTableBo, Double *currentRdCostTableBo ) 2205 { 2206 //Clean up, best_q_offset. 2207 Int64 iterOffset, tempOffset; 2208 Int64 tempDist, tempRate; 2209 Double tempCost, tempMinCost; 2210 Int64 offsetOutput = 0; 2211 iterOffset = offsetInput; 2212 // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here. 2213 tempMinCost = lambda; 2214 while (iterOffset != 0) 2215 { 2216 // Calculate the bits required for signalling the offset 2217 tempRate = (typeIdx == SAO_BO) ? (abs((Int)iterOffset)+2) : (abs((Int)iterOffset)+1); 2218 if (abs((Int)iterOffset)==m_iOffsetTh-1) 2219 { 2220 tempRate --; 2221 } 2222 // Do the dequntization before distorion calculation 2223 tempOffset = iterOffset << bitIncrease; 2224 tempDist = estSaoDist( count, tempOffset, offsetOrg, shift); 2225 tempCost = ((Double)tempDist + lambda * (Double) tempRate); 2226 if(tempCost < tempMinCost) 2227 { 2228 tempMinCost = tempCost; 2229 offsetOutput = iterOffset; 2230 if(typeIdx == SAO_BO) 2231 { 2232 currentDistortionTableBo[classIdx-1] = (Int) tempDist; 2233 currentRdCostTableBo[classIdx-1] = tempCost; 2234 } 2235 } 2236 iterOffset = (iterOffset > 0) ? (iterOffset-1):(iterOffset+1); 2237 } 2238 return offsetOutput; 2239 } 2240 2241 Void TEncSampleAdaptiveOffset::saoComponentParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Int yCbCr, Double lambda, SaoLcuParam *compSaoParam, Double *compDistortion) 2242 { 2243 Int typeIdx; 2244 Int64 estDist; 2245 Int classIdx; 2246 2247 Int shift = g_uiBitIncrement << 1; 2248 2249 Int64 bestDist; 2250 2251 SaoLcuParam* saoLcuParam = &(saoParam->saoLcuParam[yCbCr][addr]); 2252 SaoLcuParam* saoLcuParamNeighbor = NULL; 2253 2254 resetSaoUnit(saoLcuParam); 2255 resetSaoUnit(&compSaoParam[0]); 2256 resetSaoUnit(&compSaoParam[1]); 2257 2258 Double dCostPartBest = MAX_DOUBLE; 2259 2260 Double bestRDCostTableBo = MAX_DOUBLE; 2261 Int bestClassTableBo = 0; 2262 Int currentDistortionTableBo[MAX_NUM_SAO_CLASS]; 2263 Double currentRdCostTableBo[MAX_NUM_SAO_CLASS]; 2264 2265 SaoLcuParam saoLcuParamRdo; 2266 Double estRate = 0; 2267 2268 resetSaoUnit(&saoLcuParamRdo); 2269 2270 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]); 2271 m_pcRDGoOnSbacCoder->resetBits(); 2272 m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo, yCbCr); 2273 dCostPartBest = m_pcEntropyCoder->getNumberOfWrittenBits()*lambda ; 2274 2275 copySaoUnit(saoLcuParam, &saoLcuParamRdo ); 2276 2277 bestDist = 0; 2278 2279 for (typeIdx=0; typeIdx<MAX_NUM_SAO_TYPE; typeIdx++) 2280 { 2281 estDist = estSaoTypeDist(yCbCr, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo); 2282 if( typeIdx == SAO_BO ) 2283 { 2284 // Estimate Best Position 2285 Double currentRDCost = 0.0; 2286 2287 for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++) 2288 { 2289 currentRDCost = 0.0; 2290 for(UInt uj = i; uj < i+SAO_BO_LEN; uj++) 2291 { 2292 currentRDCost += currentRdCostTableBo[uj]; 2293 } 2294 2295 if( currentRDCost < bestRDCostTableBo) 2296 { 2297 bestRDCostTableBo = currentRDCost; 2298 bestClassTableBo = i; 2299 } 2300 } 2301 2302 // Re code all Offsets 2303 // Code Center 2304 estDist = 0; 2305 for(classIdx = bestClassTableBo; classIdx < bestClassTableBo+SAO_BO_LEN; classIdx++) 2306 { 2307 estDist += currentDistortionTableBo[classIdx]; 2308 } 2309 } 2310 resetSaoUnit(&saoLcuParamRdo); 2311 saoLcuParamRdo.length = m_iNumClass[typeIdx]; 2312 saoLcuParamRdo.typeIdx = typeIdx; 2313 saoLcuParamRdo.mergeLeftFlag = 0; 2314 saoLcuParamRdo.mergeUpFlag = 0; 2315 saoLcuParamRdo.subTypeIdx = (typeIdx == SAO_BO) ? bestClassTableBo : 0; 2316 for (classIdx = 0; classIdx < saoLcuParamRdo.length; classIdx++) 2317 { 2318 saoLcuParamRdo.offset[classIdx] = (Int)m_iOffset[yCbCr][typeIdx][classIdx+saoLcuParamRdo.subTypeIdx+1]; 2319 } 2320 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]); 2321 m_pcRDGoOnSbacCoder->resetBits(); 2322 m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo, yCbCr); 2323 2324 estRate = m_pcEntropyCoder->getNumberOfWrittenBits(); 2325 m_dCost[yCbCr][typeIdx] = (Double)((Double)estDist + lambda * (Double) estRate); 2326 2327 if(m_dCost[yCbCr][typeIdx] < dCostPartBest) 2328 { 2329 dCostPartBest = m_dCost[yCbCr][typeIdx]; 2330 copySaoUnit(saoLcuParam, &saoLcuParamRdo ); 2331 bestDist = estDist; 2332 } 2333 } 2334 2335 compDistortion[0] += ((Double)bestDist/lambda); 2336 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]); 2337 m_pcEntropyCoder->encodeSaoOffset(saoLcuParam, yCbCr); 2338 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[0][CI_TEMP_BEST] ); 2339 2340 // merge left or merge up 2341 for (Int idxNeighbor=0;idxNeighbor<2;idxNeighbor++) 2342 { 2343 saoLcuParamNeighbor = NULL; 2344 if (allowMergeLeft && addrLeft>=0 && idxNeighbor ==0) 2345 { 2346 saoLcuParamNeighbor = &(saoParam->saoLcuParam[yCbCr][addrLeft]); 2347 } 2348 else if (allowMergeUp && addrUp>=0 && idxNeighbor ==1) 2349 { 2350 saoLcuParamNeighbor = &(saoParam->saoLcuParam[yCbCr][addrUp]); 2351 } 2352 if (saoLcuParamNeighbor!=NULL) 2353 { 2354 estDist = 0; 2355 typeIdx = saoLcuParamNeighbor->typeIdx; 2356 if (typeIdx>=0) 2357 { 2358 Int mergeBandPosition = (typeIdx == SAO_BO)?saoLcuParamNeighbor->subTypeIdx:0; 2359 Int merge_iOffset; 2360 for(classIdx = 0; classIdx < m_iNumClass[typeIdx]; classIdx++) 2361 { 2362 merge_iOffset = saoLcuParamNeighbor->offset[classIdx]; 2363 estDist += estSaoDist(m_iCount [yCbCr][typeIdx][classIdx+mergeBandPosition+1], merge_iOffset, m_iOffsetOrg[yCbCr][typeIdx][classIdx+mergeBandPosition+1], shift); 2364 } 2365 } 2366 else 2367 { 2368 estDist = 0; 2369 } 2370 2371 copySaoUnit(&compSaoParam[idxNeighbor], saoLcuParamNeighbor ); 2372 compSaoParam[idxNeighbor].mergeUpFlag = idxNeighbor; 2373 compSaoParam[idxNeighbor].mergeLeftFlag = !idxNeighbor; 2374 2375 compDistortion[idxNeighbor+1] += ((Double)estDist/lambda); 2376 } 2377 } 2378 } 2379 2380 Void TEncSampleAdaptiveOffset::sao2ChromaParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Double lambda, SaoLcuParam *crSaoParam, SaoLcuParam *cbSaoParam, Double *distortion) 2381 { 2382 Int typeIdx; 2383 2384 Int64 estDist[2]; 2385 Int classIdx; 2386 Int shift = g_uiBitIncrement << 1; 2387 Int64 bestDist = 0; 2388 2389 SaoLcuParam* saoLcuParam[2] = {&(saoParam->saoLcuParam[1][addr]), &(saoParam->saoLcuParam[2][addr])}; 2390 SaoLcuParam* saoLcuParamNeighbor[2] = {NULL, NULL}; 2391 SaoLcuParam* saoMergeParam[2][2]; 2392 saoMergeParam[0][0] = &crSaoParam[0]; 2393 saoMergeParam[0][1] = &crSaoParam[1]; 2394 saoMergeParam[1][0] = &cbSaoParam[0]; 2395 saoMergeParam[1][1] = &cbSaoParam[1]; 2396 2397 resetSaoUnit(saoLcuParam[0]); 2398 resetSaoUnit(saoLcuParam[1]); 2399 resetSaoUnit(saoMergeParam[0][0]); 2400 resetSaoUnit(saoMergeParam[0][1]); 2401 resetSaoUnit(saoMergeParam[1][0]); 2402 resetSaoUnit(saoMergeParam[1][1]); 2403 2404 Double costPartBest = MAX_DOUBLE; 2405 2406 Double bestRDCostTableBo; 2407 Int bestClassTableBo[2] = {0, 0}; 2408 Int currentDistortionTableBo[MAX_NUM_SAO_CLASS]; 2409 Double currentRdCostTableBo[MAX_NUM_SAO_CLASS]; 2410 2411 SaoLcuParam saoLcuParamRdo[2]; 2412 Double estRate = 0; 2413 2414 resetSaoUnit(&saoLcuParamRdo[0]); 2415 resetSaoUnit(&saoLcuParamRdo[1]); 2416 2417 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]); 2418 m_pcRDGoOnSbacCoder->resetBits(); 2419 m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[0], 1); 2420 m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[1], 2); 2421 2422 costPartBest = m_pcEntropyCoder->getNumberOfWrittenBits()*lambda ; 2423 copySaoUnit(saoLcuParam[0], &saoLcuParamRdo[0] ); 2424 copySaoUnit(saoLcuParam[1], &saoLcuParamRdo[1] ); 2425 2426 for (typeIdx=0; typeIdx<MAX_NUM_SAO_TYPE; typeIdx++) 2427 { 2428 if( typeIdx == SAO_BO ) 2429 { 2430 // Estimate Best Position 2431 for(Int compIdx = 0; compIdx < 2; compIdx++) 2432 { 2433 Double currentRDCost = 0.0; 2434 bestRDCostTableBo = MAX_DOUBLE; 2435 estDist[compIdx] = estSaoTypeDist(compIdx+1, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo); 2436 2437 for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++) 2438 { 2439 currentRDCost = 0.0; 2440 for(UInt uj = i; uj < i+SAO_BO_LEN; uj++) 2441 { 2442 currentRDCost += currentRdCostTableBo[uj]; 2443 } 2444 2445 if( currentRDCost < bestRDCostTableBo) 2446 { 2447 bestRDCostTableBo = currentRDCost; 2448 bestClassTableBo[compIdx] = i; 2449 } 2450 } 2451 2452 // Re code all Offsets 2453 // Code Center 2454 estDist[compIdx] = 0; 2455 for(classIdx = bestClassTableBo[compIdx]; classIdx < bestClassTableBo[compIdx]+SAO_BO_LEN; classIdx++) 2456 { 2457 estDist[compIdx] += currentDistortionTableBo[classIdx]; 2458 } 2459 } 2460 } 2461 else 2462 { 2463 estDist[0] = estSaoTypeDist(1, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo); 2464 estDist[1] = estSaoTypeDist(2, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo); 2465 } 2466 2467 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]); 2468 m_pcRDGoOnSbacCoder->resetBits(); 2469 2470 for(Int compIdx = 0; compIdx < 2; compIdx++) 2471 { 2472 resetSaoUnit(&saoLcuParamRdo[compIdx]); 2473 saoLcuParamRdo[compIdx].length = m_iNumClass[typeIdx]; 2474 saoLcuParamRdo[compIdx].typeIdx = typeIdx; 2475 saoLcuParamRdo[compIdx].mergeLeftFlag = 0; 2476 saoLcuParamRdo[compIdx].mergeUpFlag = 0; 2477 saoLcuParamRdo[compIdx].subTypeIdx = (typeIdx == SAO_BO) ? bestClassTableBo[compIdx] : 0; 2478 for (classIdx = 0; classIdx < saoLcuParamRdo[compIdx].length; classIdx++) 2479 { 2480 saoLcuParamRdo[compIdx].offset[classIdx] = (Int)m_iOffset[compIdx+1][typeIdx][classIdx+saoLcuParamRdo[compIdx].subTypeIdx+1]; 2481 } 2482 m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[compIdx], compIdx+1); 2483 } 2484 estRate = m_pcEntropyCoder->getNumberOfWrittenBits(); 2485 m_dCost[1][typeIdx] = (Double)((Double)(estDist[0] + estDist[1]) + lambda * (Double) estRate); 2486 2487 if(m_dCost[1][typeIdx] < costPartBest) 2488 { 2489 costPartBest = m_dCost[1][typeIdx]; 2490 copySaoUnit(saoLcuParam[0], &saoLcuParamRdo[0] ); 2491 copySaoUnit(saoLcuParam[1], &saoLcuParamRdo[1] ); 2492 bestDist = (estDist[0]+estDist[1]); 2493 } 2494 } 2495 2496 distortion[0] += ((Double)bestDist/lambda); 2497 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]); 2498 m_pcEntropyCoder->encodeSaoOffset(saoLcuParam[0], 1); 2499 m_pcEntropyCoder->encodeSaoOffset(saoLcuParam[1], 2); 2500 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[0][CI_TEMP_BEST] ); 2501 2502 // merge left or merge up 2503 2504 for (Int idxNeighbor=0;idxNeighbor<2;idxNeighbor++) 2505 { 2506 for(Int compIdx = 0; compIdx < 2; compIdx++) 2507 { 2508 saoLcuParamNeighbor[compIdx] = NULL; 2509 if (allowMergeLeft && addrLeft>=0 && idxNeighbor ==0) 2510 { 2511 saoLcuParamNeighbor[compIdx] = &(saoParam->saoLcuParam[compIdx+1][addrLeft]); 2512 } 2513 else if (allowMergeUp && addrUp>=0 && idxNeighbor ==1) 2514 { 2515 saoLcuParamNeighbor[compIdx] = &(saoParam->saoLcuParam[compIdx+1][addrUp]); 2516 } 2517 if (saoLcuParamNeighbor[compIdx]!=NULL) 2518 { 2519 estDist[compIdx] = 0; 2520 typeIdx = saoLcuParamNeighbor[compIdx]->typeIdx; 2521 if (typeIdx>=0) 2522 { 2523 Int mergeBandPosition = (typeIdx == SAO_BO)?saoLcuParamNeighbor[compIdx]->subTypeIdx:0; 2524 Int merge_iOffset; 2525 for(classIdx = 0; classIdx < m_iNumClass[typeIdx]; classIdx++) 2526 { 2527 merge_iOffset = saoLcuParamNeighbor[compIdx]->offset[classIdx]; 2528 estDist[compIdx] += estSaoDist(m_iCount [compIdx+1][typeIdx][classIdx+mergeBandPosition+1], merge_iOffset, m_iOffsetOrg[compIdx+1][typeIdx][classIdx+mergeBandPosition+1], shift); 2529 } 2530 } 2531 else 2532 { 2533 estDist[compIdx] = 0; 2534 } 2535 2536 copySaoUnit(saoMergeParam[compIdx][idxNeighbor], saoLcuParamNeighbor[compIdx] ); 2537 saoMergeParam[compIdx][idxNeighbor]->mergeUpFlag = idxNeighbor; 2538 saoMergeParam[compIdx][idxNeighbor]->mergeLeftFlag = !idxNeighbor; 2539 distortion[idxNeighbor+1] += ((Double)estDist[compIdx]/lambda); 2540 } 2541 } 2542 } 2543 } 2544 #else 2545 TEncSampleAdaptiveOffset::TEncSampleAdaptiveOffset() 2546 { 2547 m_pcEntropyCoder = NULL; 2548 m_pppcRDSbacCoder = NULL; 2549 m_pcRDGoOnSbacCoder = NULL; 2550 m_pppcBinCoderCABAC = NULL; 2551 m_iCount = NULL; 2552 m_iOffset = NULL; 2553 m_iOffsetOrg = NULL; 2554 m_iRate = NULL; 2555 m_iDist = NULL; 2556 m_dCost = NULL; 2557 m_dCostPartBest = NULL; 2558 m_iDistOrg = NULL; 2559 m_iTypePartBest = NULL; 2560 } 2561 TEncSampleAdaptiveOffset::~TEncSampleAdaptiveOffset() 2562 { 2563 2564 } 2565 // ==================================================================================================================== 2566 // Constants 2567 // ==================================================================================================================== 2568 2569 2570 // ==================================================================================================================== 2571 // Tables 2572 // ==================================================================================================================== 2573 2574 inline Double xRoundIbdi2(Double x) 2575 { 2576 #if FULL_NBIT 2577 Int bitDepthMinus8 = g_uiBitDepth - 8; 2578 return ((x)>0) ? (Int)(((Int)(x)+(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8)) : ((Int)(((Int)(x)-(1<<(bitDepthMinus8-1)))/(1<<bitDepthMinus8))); 2579 #else 2580 return ((x)>0) ? (Int)(((Int)(x)+(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement)) : ((Int)(((Int)(x)-(1<<(g_uiBitIncrement-1)))/(1<<g_uiBitIncrement))); 2581 #endif 2582 } 2583 2584 /** rounding with IBDI 2585 * \param x 2586 */ 2587 inline Double xRoundIbdi(Double x) 2588 { 2589 #if FULL_NBIT 2590 return (g_uiBitDepth > 8 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ; 2591 #else 2592 return (g_uiBitIncrement >0 ? xRoundIbdi2((x)) : ((x)>=0 ? ((Int)((x)+0.5)) : ((Int)((x)-0.5)))) ; 2593 #endif 2594 } 2595 2596 2597 2598 /** process SAO for one partition 2599 * \param *psQTPart, iPartIdx, dLambda 2600 */ 2601 Void TEncSampleAdaptiveOffset::rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda) 2602 { 2603 Int iTypeIdx; 2604 Int iNumTotalType = MAX_NUM_SAO_TYPE; 2605 SAOQTPart* pOnePart = &(psQTPart[iPartIdx]); 2606 2607 Int64 iEstDist; 2608 Int64 iOffsetOrg; 2609 Int64 iOffset; 2610 Int64 iCount; 2611 Int iClassIdx; 2612 Int uiShift = g_uiBitIncrement << 1; 2613 UInt uiDepth = pOnePart->PartLevel; 2614 2615 m_iDistOrg [iPartIdx] = 0; 2616 2617 Double bestRDCostTableBo = MAX_DOUBLE; 2618 Int bestClassTableBo = 0; 2619 Int currentDistortionTableBo[MAX_NUM_SAO_CLASS]; 2620 Double currentRdCostTableBo[MAX_NUM_SAO_CLASS]; 2621 2622 #if HHI_INTERVIEW_SKIP 2623 Int iFrameWidthInCU = m_pcPic->getFrameWidthInCU(); 2624 Int LcuIdxX = psQTPart->StartCUX; 2625 Int LcuIdxY = psQTPart->StartCUY; 2626 Int iAddr = LcuIdxY*iFrameWidthInCU + LcuIdxX; 2627 TComDataCU *pcCU = m_pcPic->getCU(iAddr); 2628 Bool bRenderable = pcCU->getRenderable(0) ; 2629 2630 #endif 2631 for (iTypeIdx=-1; iTypeIdx<iNumTotalType; iTypeIdx++) 2632 { 2633 if( m_bUseSBACRD ) 2634 { 2635 m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]); 2636 m_pcRDGoOnSbacCoder->resetBits(); 2637 } 2638 else 2639 { 2640 m_pcEntropyCoder->resetEntropy(); 2641 m_pcEntropyCoder->resetBits(); 2642 } 2643 2644 iEstDist = 0; 2645 2646 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoTypeIdx(iTypeIdx+1); 2647 2648 if (iTypeIdx>=0) 2649 { 2650 2651 for(iClassIdx=1; iClassIdx < ( (iTypeIdx < SAO_BO) ? m_iNumClass[iTypeIdx]+1 : SAO_MAX_BO_CLASSES+1); iClassIdx++) 2652 { 2653 if( iTypeIdx == SAO_BO) 2654 { 2655 currentDistortionTableBo[iClassIdx-1] = 0; 2656 currentRdCostTableBo[iClassIdx-1] = dLambda; 2657 } 2658 #if HHI_INTERVIEW_SKIP 2659 if(m_iCount [iPartIdx][iTypeIdx][iClassIdx] && !bRenderable) 2660 #else 2661 if(m_iCount [iPartIdx][iTypeIdx][iClassIdx]) 2662 #endif 2663 { 2664 #if FULL_NBIT 2665 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]<<g_uiBitDepth-8) / (Double)(m_iCount [iPartIdx][iTypeIdx][iClassIdx]<<m_uiSaoBitIncrease)); 2666 #else 2667 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = (Int64) xRoundIbdi((Double)(m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]<<g_uiBitIncrement) / (Double)(m_iCount [iPartIdx][iTypeIdx][iClassIdx]<<m_uiSaoBitIncrease)); 2668 #endif 2669 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = Clip3(-m_iOffsetTh, m_iOffsetTh-1, (Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]); 2670 2671 if (iTypeIdx < 4) 2672 { 2673 if ( m_iOffset[iPartIdx][iTypeIdx][iClassIdx]<0 && iClassIdx<3 ) 2674 { 2675 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0; 2676 } 2677 if ( m_iOffset[iPartIdx][iTypeIdx][iClassIdx]>0 && iClassIdx>=3) 2678 { 2679 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0; 2680 } 2681 } 2682 { 2683 //Clean up, best_q_offset. 2684 Int64 iIterOffset, iTempOffset; 2685 Int64 iTempDist, iTempRate; 2686 Double dTempCost, dTempMinCost; 2687 UInt uiLength, uiTemp; 2688 2689 iIterOffset = m_iOffset[iPartIdx][iTypeIdx][iClassIdx]; 2690 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0; 2691 dTempMinCost = dLambda; // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here. 2692 2693 while (iIterOffset != 0) 2694 { 2695 // Calculate the bits required for signalling the offset 2696 uiLength = 1; 2697 uiTemp = (UInt)((iIterOffset <= 0) ? ( (-iIterOffset<<1) + 1 ) : (iIterOffset<<1)); 2698 while( 1 != uiTemp ) 2699 { 2700 uiTemp >>= 1; 2701 uiLength += 2; 2702 } 2703 iTempRate = (uiLength >> 1) + ((uiLength+1) >> 1); 2704 2705 // Do the dequntization before distorion calculation 2706 iTempOffset = iIterOffset << m_uiSaoBitIncrease; 2707 iTempDist = (( m_iCount [iPartIdx][iTypeIdx][iClassIdx]*iTempOffset*iTempOffset-m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]*iTempOffset*2 ) >> uiShift); 2708 2709 dTempCost = ((Double)iTempDist + dLambda * (Double) iTempRate); 2710 if(dTempCost < dTempMinCost) 2711 { 2712 dTempMinCost = dTempCost; 2713 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = iIterOffset; 2714 if(iTypeIdx == SAO_BO) 2715 { 2716 currentDistortionTableBo[iClassIdx-1] = (Int) iTempDist; 2717 currentRdCostTableBo[iClassIdx-1] = dTempCost; 2718 } 2719 } 2720 iIterOffset = (iIterOffset > 0) ? (iIterOffset-1):(iIterOffset+1); 2721 } 2722 2723 } 2724 } 2725 else 2726 { 2727 m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx] = 0; 2728 m_iOffset[iPartIdx][iTypeIdx][iClassIdx] = 0; 2729 } 2730 if( iTypeIdx != SAO_BO ) 2731 { 2732 iCount = m_iCount [iPartIdx][iTypeIdx][iClassIdx]; 2733 iOffset = m_iOffset[iPartIdx][iTypeIdx][iClassIdx] << m_uiSaoBitIncrease; 2734 iOffsetOrg = m_iOffsetOrg[iPartIdx][iTypeIdx][iClassIdx]; 2735 iEstDist += (( iCount*iOffset*iOffset-iOffsetOrg*iOffset*2 ) >> uiShift); 2736 if (iTypeIdx < 4) 2737 { 2738 if (iClassIdx<3) 2739 { 2740 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]); 2741 } 2742 else 2743 { 2744 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUvlc((Int)-m_iOffset[iPartIdx][iTypeIdx][iClassIdx]); 2745 } 2746 } 2747 else 2748 { 2749 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoSvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx]); 2750 } 2751 } 2752 } 2753 2754 if( iTypeIdx == SAO_BO ) 2755 { 2756 // Estimate Best Position 2757 Double currentRDCost = 0.0; 2758 2759 for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++) 2760 { 2761 currentRDCost = 0.0; 2762 for(UInt uj = i; uj < i+SAO_BO_LEN; uj++) 2763 { 2764 currentRDCost += currentRdCostTableBo[uj]; 2765 } 2766 2767 if( currentRDCost < bestRDCostTableBo) 2768 { 2769 bestRDCostTableBo = currentRDCost; 2770 bestClassTableBo = i; 2771 } 2772 } 2773 2774 // Re code all Offsets 2775 // Code Center 2776 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoUflc( (UInt) (bestClassTableBo) ); 2777 2778 for(iClassIdx = bestClassTableBo; iClassIdx < bestClassTableBo+SAO_BO_LEN; iClassIdx++) 2779 { 2780 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoSvlc((Int)m_iOffset[iPartIdx][iTypeIdx][iClassIdx+1]); 2781 iEstDist += currentDistortionTableBo[iClassIdx]; 2782 } 2783 } 2784 2785 m_iDist[iPartIdx][iTypeIdx] = iEstDist; 2786 m_iRate[iPartIdx][iTypeIdx] = m_pcEntropyCoder->getNumberOfWrittenBits(); 2787 2788 m_dCost[iPartIdx][iTypeIdx] = (Double)((Double)m_iDist[iPartIdx][iTypeIdx] + dLambda * (Double) m_iRate[iPartIdx][iTypeIdx]); 2789 2790 if(m_dCost[iPartIdx][iTypeIdx] < m_dCostPartBest[iPartIdx]) 2791 { 2792 m_iDistOrg [iPartIdx] = 0; 2793 m_dCostPartBest[iPartIdx] = m_dCost[iPartIdx][iTypeIdx]; 2794 m_iTypePartBest[iPartIdx] = iTypeIdx; 2795 if( m_bUseSBACRD ) 2796 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] ); 2797 } 2798 } 2799 else 2800 { 2801 if(m_iDistOrg[iPartIdx] < m_dCostPartBest[iPartIdx] ) 2802 { 2803 m_dCostPartBest[iPartIdx] = (Double) m_iDistOrg[iPartIdx] + m_pcEntropyCoder->getNumberOfWrittenBits()*dLambda ; 2804 m_iTypePartBest[iPartIdx] = -1; 2805 if( m_bUseSBACRD ) 2806 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[pOnePart->PartLevel][CI_TEMP_BEST] ); 2807 } 2808 } 2809 } 2810 2811 pOnePart->bProcessed = true; 2812 pOnePart->bSplit = false; 2813 pOnePart->iMinDist = m_iTypePartBest[iPartIdx] >= 0 ? m_iDist[iPartIdx][m_iTypePartBest[iPartIdx]] : m_iDistOrg[iPartIdx]; 2814 pOnePart->iMinRate = (Int) (m_iTypePartBest[iPartIdx] >= 0 ? m_iRate[iPartIdx][m_iTypePartBest[iPartIdx]] : 0); 2815 pOnePart->dMinCost = pOnePart->iMinDist + dLambda * pOnePart->iMinRate; 2816 pOnePart->iBestType = m_iTypePartBest[iPartIdx]; 2817 if (pOnePart->iBestType != -1) 2818 { 2819 // pOnePart->bEnableFlag = 1; 2820 pOnePart->iLength = m_iNumClass[pOnePart->iBestType]; 2821 Int minIndex = 0; 2822 if( pOnePart->iBestType == SAO_BO ) 2823 { 2824 pOnePart->bandPosition = bestClassTableBo; 2825 minIndex = pOnePart->bandPosition; 2826 } 2827 for (Int i=0; i< pOnePart->iLength ; i++) 2828 { 2829 pOnePart->iOffset[i] = (Int) m_iOffset[iPartIdx][pOnePart->iBestType][minIndex+i+1]; 2830 } 2831 2832 } 2833 else 2834 { 2835 // pOnePart->bEnableFlag = 0; 2836 pOnePart->iLength = 0; 2837 } 2838 } 2839 2840 /** Run partition tree disable 2841 */ 2842 Void TEncSampleAdaptiveOffset::disablePartTree(SAOQTPart *psQTPart, Int iPartIdx) 2843 { 2844 SAOQTPart* pOnePart= &(psQTPart[iPartIdx]); 2845 pOnePart->bSplit = false; 2846 pOnePart->iLength = 0; 2847 pOnePart->iBestType = -1; 2848 2849 if (pOnePart->PartLevel < m_uiMaxSplitLevel) 2850 { 2851 for (Int i=0; i<NUM_DOWN_PART; i++) 2852 { 2853 disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]); 2854 } 2855 } 2856 } 2857 2858 /** Run quadtree decision function 2859 * \param iPartIdx, pcPicOrg, pcPicDec, pcPicRest, &dCostFinal 2860 */ 2861 Void TEncSampleAdaptiveOffset::runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda) 2862 { 2863 SAOQTPart* pOnePart = &(psQTPart[iPartIdx]); 2864 2865 UInt uiDepth = pOnePart->PartLevel; 2866 UInt uhNextDepth = uiDepth+1; 2867 2868 if (iPartIdx == 0) 2869 { 2870 dCostFinal = 0; 2871 } 2872 2873 //SAO for this part 2874 if(!pOnePart->bProcessed) 2875 { 2876 rdoSaoOnePart (psQTPart, iPartIdx, dLambda); 2877 } 2878 2879 //SAO for sub 4 parts 2880 if (pOnePart->PartLevel < iMaxLevel) 2881 { 2882 Double dCostNotSplit = dLambda + pOnePart->dMinCost; 2883 Double dCostSplit = dLambda; 2884 2885 for (Int i=0; i< NUM_DOWN_PART ;i++) 2886 { 2887 if( m_bUseSBACRD ) 2888 { 2889 if ( 0 == i) //initialize RD with previous depth buffer 2890 { 2891 m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]); 2892 } 2893 else 2894 { 2895 m_pppcRDSbacCoder[uhNextDepth][CI_CURR_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]); 2896 } 2897 } 2898 runQuadTreeDecision(psQTPart, pOnePart->DownPartsIdx[i], dCostFinal, iMaxLevel, dLambda); 2899 dCostSplit += dCostFinal; 2900 if( m_bUseSBACRD ) 2901 { 2902 m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_TEMP_BEST]); 2903 } 2904 } 2905 2906 if(dCostSplit < dCostNotSplit) 2907 { 2908 dCostFinal = dCostSplit; 2909 pOnePart->bSplit = true; 2910 pOnePart->iLength = 0; 2911 pOnePart->iBestType = -1; 2912 if( m_bUseSBACRD ) 2913 { 2914 m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uhNextDepth][CI_NEXT_BEST]); 2915 } 2916 } 2917 else 2918 { 2919 dCostFinal = dCostNotSplit; 2920 pOnePart->bSplit = false; 2921 for (Int i=0; i<NUM_DOWN_PART; i++) 2922 { 2923 disablePartTree(psQTPart, pOnePart->DownPartsIdx[i]); 2924 } 2925 if( m_bUseSBACRD ) 2926 { 2927 m_pppcRDSbacCoder[uiDepth][CI_NEXT_BEST]->load(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]); 2928 } 2929 } 2930 } 2931 else 2932 { 2933 dCostFinal = pOnePart->dMinCost; 2934 } 2935 } 2936 2937 /** delete allocated memory of TEncSampleAdaptiveOffset class. 2938 */ 2939 Void TEncSampleAdaptiveOffset::destroyEncBuffer() 2940 { 2941 for (Int i=0;i<m_iNumTotalParts;i++) 2942 { 2943 for (Int j=0;j<MAX_NUM_SAO_TYPE;j++) 2944 { 2945 if (m_iCount [i][j]) 2946 { 2947 delete [] m_iCount [i][j]; 2948 } 2949 if (m_iOffset[i][j]) 2950 { 2951 delete [] m_iOffset[i][j]; 2952 } 2953 if (m_iOffsetOrg[i][j]) 2954 { 2955 delete [] m_iOffsetOrg[i][j]; 2956 } 2957 } 2958 if (m_iRate[i]) 2959 { 2960 delete [] m_iRate[i]; 2961 } 2962 if (m_iDist[i]) 2963 { 2964 delete [] m_iDist[i]; 2965 } 2966 if (m_dCost[i]) 2967 { 2968 delete [] m_dCost[i]; 2969 } 2970 if (m_iCount [i]) 2971 { 2972 delete [] m_iCount [i]; 2973 } 2974 if (m_iOffset[i]) 2975 { 2976 delete [] m_iOffset[i]; 2977 } 2978 if (m_iOffsetOrg[i]) 2979 { 2980 delete [] m_iOffsetOrg[i]; 2981 } 2982 2983 } 2984 if (m_iDistOrg) 2985 { 2986 delete [] m_iDistOrg ; m_iDistOrg = NULL; 2987 } 2988 if (m_dCostPartBest) 2989 { 2990 delete [] m_dCostPartBest ; m_dCostPartBest = NULL; 2991 } 2992 if (m_iTypePartBest) 2993 { 2994 delete [] m_iTypePartBest ; m_iTypePartBest = NULL; 2995 } 2996 if (m_iRate) 2997 { 2998 delete [] m_iRate ; m_iRate = NULL; 2999 } 3000 if (m_iDist) 3001 { 3002 delete [] m_iDist ; m_iDist = NULL; 3003 } 3004 if (m_dCost) 3005 { 3006 delete [] m_dCost ; m_dCost = NULL; 3007 } 3008 if (m_iCount) 3009 { 3010 delete [] m_iCount ; m_iCount = NULL; 3011 } 3012 if (m_iOffset) 3013 { 3014 delete [] m_iOffset ; m_iOffset = NULL; 3015 } 3016 if (m_iOffsetOrg) 3017 { 3018 delete [] m_iOffsetOrg ; m_iOffsetOrg = NULL; 3019 } 3020 3021 Int iMaxDepth = 4; 3022 Int iDepth; 3023 for ( iDepth = 0; iDepth < iMaxDepth+1; iDepth++ ) 3024 { 3025 for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ ) 3026 { 3027 delete m_pppcRDSbacCoder[iDepth][iCIIdx]; 3028 delete m_pppcBinCoderCABAC[iDepth][iCIIdx]; 3029 } 3030 } 3031 3032 for ( iDepth = 0; iDepth < iMaxDepth+1; iDepth++ ) 3033 { 3034 delete [] m_pppcRDSbacCoder[iDepth]; 3035 delete [] m_pppcBinCoderCABAC[iDepth]; 3036 } 3037 3038 delete [] m_pppcRDSbacCoder; 3039 delete [] m_pppcBinCoderCABAC; 3040 } 3041 3042 /** create Encoder Buffer for SAO 3043 * \param 3044 */ 3045 Void TEncSampleAdaptiveOffset::createEncBuffer() 3046 { 3047 m_iDistOrg = new Int64 [m_iNumTotalParts]; 3048 m_dCostPartBest = new Double [m_iNumTotalParts]; 3049 m_iTypePartBest = new Int [m_iNumTotalParts]; 3050 3051 m_iRate = new Int64* [m_iNumTotalParts]; 3052 m_iDist = new Int64* [m_iNumTotalParts]; 3053 m_dCost = new Double*[m_iNumTotalParts]; 3054 3055 m_iCount = new Int64 **[m_iNumTotalParts]; 3056 m_iOffset = new Int64 **[m_iNumTotalParts]; 3057 m_iOffsetOrg = new Int64 **[m_iNumTotalParts]; 3058 3059 for (Int i=0;i<m_iNumTotalParts;i++) 3060 { 3061 m_iRate[i] = new Int64 [MAX_NUM_SAO_TYPE]; 3062 m_iDist[i] = new Int64 [MAX_NUM_SAO_TYPE]; 3063 m_dCost[i] = new Double [MAX_NUM_SAO_TYPE]; 3064 3065 m_iCount [i] = new Int64 *[MAX_NUM_SAO_TYPE]; 3066 m_iOffset[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 3067 m_iOffsetOrg[i] = new Int64 *[MAX_NUM_SAO_TYPE]; 3068 3069 for (Int j=0;j<MAX_NUM_SAO_TYPE;j++) 3070 { 3071 m_iCount [i][j] = new Int64 [MAX_NUM_SAO_CLASS]; 3072 m_iOffset[i][j] = new Int64 [MAX_NUM_SAO_CLASS]; 3073 m_iOffsetOrg[i][j]= new Int64 [MAX_NUM_SAO_CLASS]; 3074 } 3075 } 3076 3077 Int iMaxDepth = 4; 3078 m_pppcRDSbacCoder = new TEncSbac** [iMaxDepth+1]; 3079 #if FAST_BIT_EST 3080 m_pppcBinCoderCABAC = new TEncBinCABACCounter** [iMaxDepth+1]; 3081 #else 3082 m_pppcBinCoderCABAC = new TEncBinCABAC** [iMaxDepth+1]; 3083 #endif 3084 3085 for ( Int iDepth = 0; iDepth < iMaxDepth+1; iDepth++ ) 3086 { 3087 m_pppcRDSbacCoder[iDepth] = new TEncSbac* [CI_NUM]; 3088 #if FAST_BIT_EST 3089 m_pppcBinCoderCABAC[iDepth] = new TEncBinCABACCounter* [CI_NUM]; 3090 #else 3091 m_pppcBinCoderCABAC[iDepth] = new TEncBinCABAC* [CI_NUM]; 3092 #endif 3093 for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ ) 3094 { 3095 m_pppcRDSbacCoder[iDepth][iCIIdx] = new TEncSbac; 3096 #if FAST_BIT_EST 3097 m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABACCounter; 3098 #else 3099 m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABAC; 3100 #endif 3101 m_pppcRDSbacCoder [iDepth][iCIIdx]->init( m_pppcBinCoderCABAC [iDepth][iCIIdx] ); 3102 } 3103 } 3104 } 3105 3106 /** Start SAO encoder 3107 * \param pcPic, pcEntropyCoder, pppcRDSbacCoder, pcRDGoOnSbacCoder 3108 */ 3109 Void TEncSampleAdaptiveOffset::startSaoEnc( TComPic* pcPic, TEncEntropy* pcEntropyCoder, TEncSbac*** pppcRDSbacCoder, TEncSbac* pcRDGoOnSbacCoder) 3110 { 3111 if( pcRDGoOnSbacCoder ) 3112 m_bUseSBACRD = true; 3113 else 3114 m_bUseSBACRD = false; 3115 3116 m_pcPic = pcPic; 3117 m_pcEntropyCoder = pcEntropyCoder; 3118 3119 m_pcRDGoOnSbacCoder = pcRDGoOnSbacCoder; 3120 m_pcEntropyCoder->resetEntropy(); 3121 m_pcEntropyCoder->resetBits(); 3122 3123 if( m_bUseSBACRD ) 3124 { 3125 m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[0][CI_NEXT_BEST]); 3126 m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_NEXT_BEST]); 3127 } 3128 } 3129 3130 /** End SAO encoder 3131 */ 3132 Void TEncSampleAdaptiveOffset::endSaoEnc() 3133 { 3134 m_pcPic = NULL; 3135 m_pcEntropyCoder = NULL; 3136 } 3137 3138 inline int xSign(int x) 3139 { 3140 return ((x >> 31) | ((int)( (((unsigned int) -x)) >> 31))); 3141 } 3142 3143 /** Calculate SAO statistics for non-cross-slice or non-cross-tile processing 3144 * \param pRecStart to-be-filtered block buffer pointer 3145 * \param pOrgStart original block buffer pointer 3146 * \param stride picture buffer stride 3147 * \param ppStat statistics buffer 3148 * \param ppCount counter buffer 3149 * \param width block width 3150 * \param height block height 3151 * \param pbBorderAvail availabilities of block border pixels 3152 */ 3153 Void TEncSampleAdaptiveOffset::calcSaoStatsBlock( Pel* pRecStart, Pel* pOrgStart, Int stride, Int64** ppStats, Int64** ppCount, UInt width, UInt height, Bool* pbBorderAvail) 3154 { 3155 Int64 *stats, *count; 3156 Int classIdx, posShift, startX, endX, startY, endY, signLeft,signRight,signDown,signDown1; 3157 Pel *pOrg, *pRec; 3158 UInt edgeType; 3159 Int x, y; 3160 3161 //--------- Band offset-----------// 3162 stats = ppStats[SAO_BO]; 3163 count = ppCount[SAO_BO]; 3164 pOrg = pOrgStart; 3165 pRec = pRecStart; 3166 for (y=0; y< height; y++) 3167 { 3168 for (x=0; x< width; x++) 3169 { 3170 classIdx = m_lumaTableBo[pRec[x]]; 3171 if (classIdx) 3172 { 3173 stats[classIdx] += (pOrg[x] - pRec[x]); 3174 count[classIdx] ++; 3175 } 3176 } 3177 pOrg += stride; 3178 pRec += stride; 3179 } 3180 //---------- Edge offset 0--------------// 3181 stats = ppStats[SAO_EO_0]; 3182 count = ppCount[SAO_EO_0]; 3183 pOrg = pOrgStart; 3184 pRec = pRecStart; 3185 3186 3187 startX = (pbBorderAvail[SGU_L]) ? 0 : 1; 3188 endX = (pbBorderAvail[SGU_R]) ? width : (width -1); 3189 for (y=0; y< height; y++) 3190 { 3191 signLeft = xSign(pRec[startX] - pRec[startX-1]); 3192 for (x=startX; x< endX; x++) 3193 { 3194 signRight = xSign(pRec[x] - pRec[x+1]); 3195 edgeType = signRight + signLeft + 2; 3196 signLeft = -signRight; 3197 3198 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3199 count[m_auiEoTable[edgeType]] ++; 3200 } 3201 pRec += stride; 3202 pOrg += stride; 3203 } 3204 3205 //---------- Edge offset 1--------------// 3206 stats = ppStats[SAO_EO_1]; 3207 count = ppCount[SAO_EO_1]; 3208 pOrg = pOrgStart; 3209 pRec = pRecStart; 3210 3211 startY = (pbBorderAvail[SGU_T]) ? 0 : 1; 3212 endY = (pbBorderAvail[SGU_B]) ? height : height-1; 3213 if (!pbBorderAvail[SGU_T]) 3214 { 3215 pRec += stride; 3216 pOrg += stride; 3217 } 3218 3219 for (x=0; x< width; x++) 3220 { 3221 m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-stride]); 3222 } 3223 for (y=startY; y<endY; y++) 3224 { 3225 for (x=0; x< width; x++) 3226 { 3227 signDown = xSign(pRec[x] - pRec[x+stride]); 3228 edgeType = signDown + m_iUpBuff1[x] + 2; 3229 m_iUpBuff1[x] = -signDown; 3230 3231 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3232 count[m_auiEoTable[edgeType]] ++; 3233 } 3234 pOrg += stride; 3235 pRec += stride; 3236 } 3237 //---------- Edge offset 2--------------// 3238 stats = ppStats[SAO_EO_2]; 3239 count = ppCount[SAO_EO_2]; 3240 pOrg = pOrgStart; 3241 pRec = pRecStart; 3242 3243 posShift= stride + 1; 3244 3245 startX = (pbBorderAvail[SGU_L]) ? 0 : 1 ; 3246 endX = (pbBorderAvail[SGU_R]) ? width : (width-1); 3247 3248 //prepare 2nd line upper sign 3249 pRec += stride; 3250 for (x=startX; x< endX+1; x++) 3251 { 3252 m_iUpBuff1[x] = xSign(pRec[x] - pRec[x- posShift]); 3253 } 3254 3255 //1st line 3256 pRec -= stride; 3257 if(pbBorderAvail[SGU_TL]) 3258 { 3259 x= 0; 3260 edgeType = xSign(pRec[x] - pRec[x- posShift]) - m_iUpBuff1[x+1] + 2; 3261 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3262 count[m_auiEoTable[edgeType]] ++; 3263 } 3264 if(pbBorderAvail[SGU_T]) 3265 { 3266 for(x= 1; x< endX; x++) 3267 { 3268 edgeType = xSign(pRec[x] - pRec[x- posShift]) - m_iUpBuff1[x+1] + 2; 3269 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3270 count[m_auiEoTable[edgeType]] ++; 3271 } 3272 } 3273 pRec += stride; 3274 pOrg += stride; 3275 3276 //middle lines 3277 for (y= 1; y< height-1; y++) 3278 { 3279 for (x=startX; x<endX; x++) 3280 { 3281 signDown1 = xSign(pRec[x] - pRec[x+ posShift]) ; 3282 edgeType = signDown1 + m_iUpBuff1[x] + 2; 3283 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3284 count[m_auiEoTable[edgeType]] ++; 3285 3286 m_iUpBufft[x+1] = -signDown1; 3287 } 3288 m_iUpBufft[startX] = xSign(pRec[stride+startX] - pRec[startX-1]); 3289 3290 ipSwap = m_iUpBuff1; 3291 m_iUpBuff1 = m_iUpBufft; 3292 m_iUpBufft = ipSwap; 3293 3294 pRec += stride; 3295 pOrg += stride; 3296 } 3297 3298 //last line 3299 if(pbBorderAvail[SGU_B]) 3300 { 3301 for(x= startX; x< width-1; x++) 3302 { 3303 edgeType = xSign(pRec[x] - pRec[x+ posShift]) + m_iUpBuff1[x] + 2; 3304 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3305 count[m_auiEoTable[edgeType]] ++; 3306 } 3307 } 3308 if(pbBorderAvail[SGU_BR]) 3309 { 3310 x= width -1; 3311 edgeType = xSign(pRec[x] - pRec[x+ posShift]) + m_iUpBuff1[x] + 2; 3312 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3313 count[m_auiEoTable[edgeType]] ++; 3314 } 3315 3316 //---------- Edge offset 3--------------// 3317 3318 stats = ppStats[SAO_EO_3]; 3319 count = ppCount[SAO_EO_3]; 3320 pOrg = pOrgStart; 3321 pRec = pRecStart; 3322 3323 posShift = stride - 1; 3324 startX = (pbBorderAvail[SGU_L]) ? 0 : 1; 3325 endX = (pbBorderAvail[SGU_R]) ? width : (width -1); 3326 3327 //prepare 2nd line upper sign 3328 pRec += stride; 3329 for (x=startX-1; x< endX; x++) 3330 { 3331 m_iUpBuff1[x] = xSign(pRec[x] - pRec[x- posShift]); 3332 } 3333 3334 3335 //first line 3336 pRec -= stride; 3337 if(pbBorderAvail[SGU_T]) 3338 { 3339 for(x= startX; x< width -1; x++) 3340 { 3341 edgeType = xSign(pRec[x] - pRec[x- posShift]) -m_iUpBuff1[x-1] + 2; 3342 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3343 count[m_auiEoTable[edgeType]] ++; 3344 } 3345 } 3346 if(pbBorderAvail[SGU_TR]) 3347 { 3348 x= width-1; 3349 edgeType = xSign(pRec[x] - pRec[x- posShift]) -m_iUpBuff1[x-1] + 2; 3350 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3351 count[m_auiEoTable[edgeType]] ++; 3352 } 3353 pRec += stride; 3354 pOrg += stride; 3355 3356 //middle lines 3357 for (y= 1; y< height-1; y++) 3358 { 3359 for(x= startX; x< endX; x++) 3360 { 3361 signDown1 = xSign(pRec[x] - pRec[x+ posShift]) ; 3362 edgeType = signDown1 + m_iUpBuff1[x] + 2; 3363 3364 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3365 count[m_auiEoTable[edgeType]] ++; 3366 m_iUpBuff1[x-1] = -signDown1; 3367 3368 } 3369 m_iUpBuff1[endX-1] = xSign(pRec[endX-1 + stride] - pRec[endX]); 3370 3371 pRec += stride; 3372 pOrg += stride; 3373 } 3374 3375 //last line 3376 if(pbBorderAvail[SGU_BL]) 3377 { 3378 x= 0; 3379 edgeType = xSign(pRec[x] - pRec[x+ posShift]) + m_iUpBuff1[x] + 2; 3380 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3381 count[m_auiEoTable[edgeType]] ++; 3382 3383 } 3384 if(pbBorderAvail[SGU_B]) 3385 { 3386 for(x= 1; x< endX; x++) 3387 { 3388 edgeType = xSign(pRec[x] - pRec[x+ posShift]) + m_iUpBuff1[x] + 2; 3389 stats[m_auiEoTable[edgeType]] += (pOrg[x] - pRec[x]); 3390 count[m_auiEoTable[edgeType]] ++; 3391 } 3392 } 3393 } 3394 3395 /** Calculate SAO statistics for current LCU 3396 * \param iAddr, iPartIdx, iYCbCr 3397 */ 3398 Void TEncSampleAdaptiveOffset::calcSaoStatsCu(Int iAddr, Int iPartIdx, Int iYCbCr) 3399 { 3400 if(!m_bUseNIF) 3401 { 3402 calcSaoStatsCuOrg( iAddr, iPartIdx, iYCbCr); 3403 } 3404 else 3405 { 3406 Int64** ppStats = m_iOffsetOrg[iPartIdx]; 3407 Int64** ppCount = m_iCount [iPartIdx]; 3408 3409 //parameters 3410 Int isChroma = (iYCbCr != 0)? 1:0; 3411 Int stride = (iYCbCr != 0)?(m_pcPic->getCStride()):(m_pcPic->getStride()); 3412 Pel* pPicOrg = getPicYuvAddr (m_pcPic->getPicYuvOrg(), iYCbCr); 3413 Pel* pPicRec = getPicYuvAddr(m_pcYuvTmp, iYCbCr); 3414 3415 std::vector<NDBFBlockInfo>& vFilterBlocks = *(m_pcPic->getCU(iAddr)->getNDBFilterBlocks()); 3416 3417 //variables 3418 UInt xPos, yPos, width, height; 3419 Bool* pbBorderAvail; 3420 UInt posOffset; 3421 3422 for(Int i=0; i< vFilterBlocks.size(); i++) 3423 { 3424 xPos = vFilterBlocks[i].posX >> isChroma; 3425 yPos = vFilterBlocks[i].posY >> isChroma; 3426 width = vFilterBlocks[i].width >> isChroma; 3427 height = vFilterBlocks[i].height >> isChroma; 3428 pbBorderAvail = vFilterBlocks[i].isBorderAvailable; 3429 3430 posOffset = (yPos* stride) + xPos; 3431 3432 #if HHI_INTERVIEW_SKIP 3433 if( !m_pcPic->getCU(iAddr)->getRenderable(0 )) 3434 { 3435 calcSaoStatsBlock(pPicRec+ posOffset, pPicOrg+ posOffset, stride, ppStats, ppCount,width, height, pbBorderAvail); 3436 } 3437 #else 3438 calcSaoStatsBlock(pPicRec+ posOffset, pPicOrg+ posOffset, stride, ppStats, ppCount,width, height, pbBorderAvail); 3439 #endif 3440 } 3441 } 3442 3443 } 3444 3445 /** Calculate SAO statistics for current LCU without non-crossing slice 3446 * \param iAddr, iPartIdx, iYCbCr 3447 */ 3448 Void TEncSampleAdaptiveOffset::calcSaoStatsCuOrg(Int iAddr, Int iPartIdx, Int iYCbCr) 3449 { 3450 Int x,y; 3451 TComDataCU *pTmpCu = m_pcPic->getCU(iAddr); 3452 TComSPS *pTmpSPS = m_pcPic->getSlice(0)->getSPS(); 3453 3454 Pel* pOrg; 3455 Pel* pRec; 3456 Int iStride; 3457 Int iLcuWidth = pTmpSPS->getMaxCUHeight(); 3458 Int iLcuHeight = pTmpSPS->getMaxCUWidth(); 3459 UInt uiLPelX = pTmpCu->getCUPelX(); 3460 UInt uiTPelY = pTmpCu->getCUPelY(); 3461 UInt uiRPelX; 3462 UInt uiBPelY; 3463 Int64* iStats; 3464 Int64* iCount; 3465 Int iClassIdx; 3466 Int iPicWidthTmp; 3467 Int iPicHeightTmp; 3468 Int iStartX; 3469 Int iStartY; 3470 Int iEndX; 3471 Int iEndY; 3472 3473 Int iIsChroma = (iYCbCr!=0)? 1:0; 3474 Int numSkipLine = iIsChroma? 2:4; 976 3475 if (m_saoInterleavingFlag == 0) 977 3476 { … … 1974 4473 1975 4474 } 4475 #endif 1976 4476 1977 4477 -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h
r296 r408 71 71 Int64 ***m_iOffset; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS]; 72 72 Int64 ***m_iOffsetOrg; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE]; 73 #if LGE_SAO_MIGRATION_D0091 74 Int64 ****m_count_PreDblk; //[LCU][YCbCr][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS]; 75 Int64 ****m_offsetOrg_PreDblk; //[LCU][YCbCr][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS]; 76 #endif 73 77 Int64 **m_iRate; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE]; 74 78 Int64 **m_iDist; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE]; … … 79 83 Int m_iOffsetTh; 80 84 Bool m_bUseSBACRD; 85 #if SAO_ENCODING_CHOICE 86 #if SAO_ENCODING_CHOICE_CHROMA 87 Double m_depthSaoRate[2][4]; 88 #else 89 Double m_depth0SaoRate; 90 #endif 91 #endif 81 92 82 93 public: … … 88 99 Void resetStats(); 89 100 #if SAO_CHROMA_LAMBDA 101 #if SAO_ENCODING_CHOICE 102 Void SAOProcess(SAOParam *pcSaoParam, Double dLambda, Double dLambdaChroma, Int depth); 103 #else 90 104 Void SAOProcess(SAOParam *pcSaoParam, Double dLambda, Double dLambdaChroma); 105 #endif 91 106 #else 92 107 Void SAOProcess(SAOParam *pcSaoParam, Double dLambda); 93 108 #endif 109 110 #if LGE_SAO_MIGRATION_D0091 111 Void runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda, Int yCbCr); 112 Void rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda, Int yCbCr); 113 #else 94 114 Void runQuadTreeDecision(SAOQTPart *psQTPart, Int iPartIdx, Double &dCostFinal, Int iMaxLevel, Double dLambda); 95 115 Void rdoSaoOnePart(SAOQTPart *psQTPart, Int iPartIdx, Double dLambda); 116 #endif 117 96 118 Void disablePartTree(SAOQTPart *psQTPart, Int iPartIdx); 97 119 Void getSaoStats(SAOQTPart *psQTPart, Int iYCbCr); … … 99 121 Void calcSaoStatsBlock( Pel* pRecStart, Pel* pOrgStart, Int stride, Int64** ppStats, Int64** ppCount, UInt width, UInt height, Bool* pbBorderAvail); 100 122 Void calcSaoStatsCuOrg(Int iAddr, Int iPartIdx, Int iYCbCr); 123 #if LGE_SAO_MIGRATION_D0091 124 Void calcSaoStatsCu_BeforeDblk( TComPic* pcPic ); 125 #endif 101 126 Void destroyEncBuffer(); 102 127 Void createEncBuffer(); 103 128 Void assignSaoUnitSyntax(SaoLcuParam* saoLcuParam, SAOQTPart* saoPart, Bool &oneUnitFlag, Int yCbCr); 104 129 Void checkMerge(SaoLcuParam * lcuParamCurr,SaoLcuParam * lcuParamCheck, Int dir); 130 #if SAO_ENCODING_CHOICE 131 Void rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma, Int depth); 132 #else 105 133 Void rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma); 134 #endif 135 #if LGE_SAO_MIGRATION_D0091 136 Void saoComponentParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Int yCbCr, Double lambda, SaoLcuParam *compSaoParam, Double *distortion); 137 Void sao2ChromaParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Double lambda, SaoLcuParam *crSaoParam, SaoLcuParam *cbSaoParam, Double *distortion); 138 inline Int64 estSaoDist(Int64 count, Int64 offset, Int64 offsetOrg, Int shift); 139 inline Int64 estIterOffset(Int typeIdx, Int classIdx, double lambda, Int64 offsetInput, Int64 count, Int64 offsetOrg, Int shift, Int bitIncrease, Int *currentDistortionTableBo, Double *currentRdCostTableBo ); 140 inline Int64 estSaoTypeDist(Int compIdx, Int typeIdx, Int shift, Double lambda, Int *currentDistortionTableBo, Double *currentRdCostTableBo); 141 #else 106 142 Void rdoSaoUnit(SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Int yCbCr, Double lambda); 143 #endif 107 144 Void setMaxNumOffsetsPerPic(Int iVal) {m_maxNumOffsetsPerPic = iVal; } 108 145 Int getMaxNumOffsetsPerPic() {return m_maxNumOffsetsPerPic; } -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncSbac.cpp
r332 r408 96 96 , m_cALFSvlcSCModel ( 1, 1, NUM_ALF_SVLC_CTX , m_contextModels + m_numContextModels, m_numContextModels) 97 97 , m_cCUAMPSCModel ( 1, 1, NUM_CU_AMP_CTX , m_contextModels + m_numContextModels, m_numContextModels) 98 #if LGE_SAO_MIGRATION_D0091 99 , m_cSaoMergeSCModel ( 1, 1, NUM_SAO_MERGE_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) 100 , m_cSaoTypeIdxSCModel ( 1, 1, NUM_SAO_TYPE_IDX_CTX , m_contextModels + m_numContextModels, m_numContextModels) 101 #else 98 102 , m_cSaoFlagSCModel ( 1, 1, NUM_SAO_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) 99 103 , m_cSaoUvlcSCModel ( 1, 1, NUM_SAO_UVLC_CTX , m_contextModels + m_numContextModels, m_numContextModels) … … 102 106 , m_cSaoMergeUpSCModel ( 1, 1, NUM_SAO_MERGE_UP_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) 103 107 , m_cSaoTypeIdxSCModel ( 1, 1, NUM_SAO_TYPE_IDX_CTX , m_contextModels + m_numContextModels, m_numContextModels) 108 #endif 104 109 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX 105 110 , m_cDmmFlagSCModel ( 1, 1, NUM_DMM_FLAG_CTX , m_contextModels + m_numContextModels, m_numContextModels) … … 180 185 m_cALFSvlcSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_ALF_SVLC ); 181 186 m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANS_SUBDIV_FLAG ); 187 #if LGE_SAO_MIGRATION_D0091 188 m_cSaoMergeSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_FLAG ); 189 m_cSaoTypeIdxSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX ); 190 #else 182 191 m_cSaoFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_FLAG ); 183 192 m_cSaoUvlcSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_UVLC ); … … 186 195 m_cSaoMergeUpSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_UP_FLAG ); 187 196 m_cSaoTypeIdxSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX ); 197 #endif 188 198 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX 189 199 m_cDmmFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_DMM_FLAG ); … … 266 276 curCost += m_cALFSvlcSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_ALF_SVLC ); 267 277 curCost += m_cCUTransSubdivFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_TRANS_SUBDIV_FLAG ); 278 #if LGE_SAO_MIGRATION_D0091 279 curCost += m_cSaoMergeSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SAO_MERGE_FLAG ); 280 curCost += m_cSaoTypeIdxSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SAO_TYPE_IDX ); 281 #else 268 282 curCost += m_cSaoFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SAO_FLAG ); 269 283 curCost += m_cSaoUvlcSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SAO_UVLC ); … … 272 286 curCost += m_cSaoMergeUpSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SAO_MERGE_UP_FLAG ); 273 287 curCost += m_cSaoTypeIdxSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_SAO_TYPE_IDX ); 288 #endif 274 289 275 290 if (curCost < bestCost) … … 333 348 m_cALFSvlcSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_ALF_SVLC ); 334 349 m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANS_SUBDIV_FLAG ); 350 #if LGE_SAO_MIGRATION_D0091 351 m_cSaoMergeSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_FLAG ); 352 m_cSaoTypeIdxSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX ); 353 #else 335 354 m_cSaoFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_FLAG ); 336 355 m_cSaoUvlcSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_UVLC ); … … 339 358 m_cSaoMergeUpSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_UP_FLAG ); 340 359 m_cSaoTypeIdxSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX ); 360 #endif 341 361 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX 342 362 m_cDmmFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_DMM_FLAG ); … … 1887 1907 } 1888 1908 } 1889 1909 #if LGE_SAO_MIGRATION_D0091 1910 Void TEncSbac::codeSAOSign( UInt code ) 1911 { 1912 m_pcBinIf->encodeBinEP( code ); 1913 } 1914 1915 Void TEncSbac::codeSaoMaxUvlc ( UInt code, UInt maxSymbol ) 1916 { 1917 if (maxSymbol == 0) 1918 { 1919 return; 1920 } 1921 1922 Int i; 1923 Bool bCodeLast = ( maxSymbol > code ); 1924 1925 if ( code == 0 ) 1926 { 1927 m_pcBinIf->encodeBinEP( 0 ); 1928 } 1929 else 1930 { 1931 m_pcBinIf->encodeBinEP( 1 ); 1932 for ( i=0; i<code-1; i++ ) 1933 { 1934 m_pcBinIf->encodeBinEP( 1 ); 1935 } 1936 if( bCodeLast ) 1937 { 1938 m_pcBinIf->encodeBinEP( 0 ); 1939 } 1940 } 1941 } 1942 1943 /** Code SAO EO class or BO band position 1944 * \param uiLength 1945 * \param uiCode 1946 */ 1947 Void TEncSbac::codeSaoUflc ( UInt uiLength, UInt uiCode ) 1948 { 1949 m_pcBinIf->encodeBinsEP ( uiCode, uiLength ); 1950 } 1951 /** Code SAO merge flags 1952 * \param uiCode 1953 * \param uiCompIdx 1954 */ 1955 Void TEncSbac::codeSaoMerge ( UInt uiCode ) 1956 { 1957 if (uiCode == 0) 1958 { 1959 m_pcBinIf->encodeBin(0, m_cSaoMergeSCModel.get( 0, 0, 0 )); 1960 } 1961 else 1962 { 1963 m_pcBinIf->encodeBin(1, m_cSaoMergeSCModel.get( 0, 0, 0 )); 1964 } 1965 } 1966 /** Code SAO type index 1967 * \param uiCode 1968 */ 1969 Void TEncSbac::codeSaoTypeIdx ( UInt uiCode) 1970 { 1971 if (uiCode == 0) 1972 { 1973 m_pcBinIf->encodeBin( 0, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) ); 1974 } 1975 else 1976 { 1977 m_pcBinIf->encodeBin( 1, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) ); 1978 m_pcBinIf->encodeBinEP( uiCode <= 4 ? 1 : 0 ); //determine edge or band 1979 } 1980 } 1981 #else 1890 1982 Void TEncSbac::codeSaoFlag ( UInt uiCode ) 1891 1983 { … … 2003 2095 } 2004 2096 } 2097 #endif 2005 2098 /*! 2006 2099 **************************************************************************** -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncSbac.h
r332 r408 126 126 Void codeAlfCtrlFlag ( UInt uiSymbol ); 127 127 Void codeApsExtensionFlag () { assert (0); return; }; 128 #if LGE_SAO_MIGRATION_D0091 129 Void codeSaoMaxUvlc ( UInt code, UInt maxSymbol ); 130 Void codeSaoMerge ( UInt uiCode ); 131 Void codeSaoTypeIdx ( UInt uiCode); 132 Void codeSaoUflc ( UInt uiLength, UInt uiCode ); 133 Void codeSAOSign ( UInt uiCode); //<! code SAO offset sign 134 #else 128 135 Void codeSaoFlag ( UInt uiCode ); 129 136 Void codeSaoUvlc ( UInt uiCode ); … … 134 141 Void codeSaoTypeIdx ( UInt uiCode); 135 142 Void codeSaoUflc ( UInt uiCode); 143 #endif 136 144 Void codeScalingList ( TComScalingList* scalingList ){ assert (0); return;}; 137 145 … … 292 300 ContextModel3DBuffer m_cALFSvlcSCModel; 293 301 ContextModel3DBuffer m_cCUAMPSCModel; 302 #if LGE_SAO_MIGRATION_D0091 303 ContextModel3DBuffer m_cSaoMergeSCModel; 304 ContextModel3DBuffer m_cSaoTypeIdxSCModel; 305 #else 294 306 ContextModel3DBuffer m_cSaoFlagSCModel; 295 307 ContextModel3DBuffer m_cSaoUvlcSCModel; … … 298 310 ContextModel3DBuffer m_cSaoMergeUpSCModel; 299 311 ContextModel3DBuffer m_cSaoTypeIdxSCModel; 312 #endif 300 313 301 314 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncSearch.cpp
r384 r408 2973 2973 #endif 2974 2974 2975 2976 2975 #if H3D_IVMP 2977 2976 const int maxNumMergeCand = MRG_MAX_NUM_CANDS_SIGNALED + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 ); … … 2998 2997 { 2999 2998 Int iVSPIdx = 0; 2999 #if LGE_VSP_INHERIT_D0092 3000 if (iVSPIndexTrue[uiMergeCand] == 1) 3001 { 3002 iVSPIdx = 1; 3003 } 3004 #else 3000 3005 Int numVSPIdx; 3001 3006 numVSPIdx = 3; … … 3008 3013 } 3009 3014 } 3015 #endif 3010 3016 pcCU->setVSPIndexSubParts( iVSPIdx, uiAbsPartIdx, iPUIdx, pcCU->getDepth( uiAbsPartIdx ) ); 3011 #if QC_BVSP_CleanUP_D0191 3017 #if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092 3012 3018 if(iVSPIdx != 0) 3013 3019 { … … 3679 3685 UInt uiMRGIndex = 0; 3680 3686 #if MERL_VSP_C0152 3687 #if LGE_VSP_INHERIT_D0092 3688 Int iVSPIndexTrue[MRG_MAX_NUM_CANDS_MEM]; 3689 for (Int i=0; i<MRG_MAX_NUM_CANDS_MEM; i++) 3690 { 3691 iVSPIndexTrue[i] = 0; 3692 } 3693 #else 3681 3694 Int iVSPIndexTrue[3] = {-1, -1, -1}; 3695 #endif 3682 3696 #endif 3683 3697 UInt uiMEInterDir = 0; … … 3735 3749 { 3736 3750 Int iVSPIdx = 0; 3751 #if LGE_VSP_INHERIT_D0092 3752 if (iVSPIndexTrue[uiMRGIndex] == 1) 3753 { 3754 iVSPIdx = 1; 3755 } 3756 #else 3737 3757 Int numVSPIdx; 3738 3758 numVSPIdx = 3; … … 3745 3765 } 3746 3766 } 3767 #endif 3747 3768 pcCU->setVSPIndexSubParts( iVSPIdx, uiPartAddr, iPartIdx, pcCU->getDepth( uiPartAddr ) ); 3748 #if QC_BVSP_CleanUP_D0191 3769 #if QC_BVSP_CleanUP_D0191 && !LGE_VSP_INHERIT_D0092 3749 3770 if(iVSPIdx != 0) 3750 3771 { -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncSlice.cpp
r374 r408 1205 1205 TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr ); 1206 1206 1207 #if LGE_SAO_MIGRATION_D0091 1208 if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) ) 1209 { 1210 SAOParam *saoParam = pcSlice->getAPS()->getSaoParam(); 1211 Int iNumCuInWidth = saoParam->numCuInWidth; 1212 Int iCUAddrInSlice = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU()); 1213 Int iCUAddrUpInSlice = iCUAddrInSlice - iNumCuInWidth; 1214 Int rx = uiCUAddr % iNumCuInWidth; 1215 Int ry = uiCUAddr / iNumCuInWidth; 1216 Int allowMergeLeft = 1; 1217 Int allowMergeUp = 1; 1218 1219 if (rx!=0) 1220 { 1221 if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)) 1222 { 1223 allowMergeLeft = 0; 1224 } 1225 } 1226 if (ry!=0) 1227 { 1228 if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)) 1229 { 1230 allowMergeUp = 0; 1231 } 1232 } 1233 1234 Int addr = pcCU->getAddr(); 1235 allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0); 1236 allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0); 1237 1238 if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] ) 1239 { 1240 Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag; 1241 Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag; 1242 1243 if (allowMergeLeft) 1244 { 1245 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 1246 } 1247 else 1248 { 1249 mergeLeft = 0; 1250 } 1251 if(mergeLeft == 0) 1252 { 1253 if (allowMergeUp) 1254 { 1255 m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp); 1256 } 1257 else 1258 { 1259 mergeUp = 0; 1260 } 1261 if(mergeUp == 0) 1262 { 1263 for (Int compIdx=0;compIdx<3;compIdx++) 1264 { 1265 if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1])) 1266 { 1267 m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx); 1268 } 1269 } 1270 } 1271 } 1272 } 1273 } 1274 #else 1207 1275 if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() ) 1208 1276 { 1209 Int iNumCuInWidth = pcSlice->getAPS()->getSaoParam()->numCuInWidth; 1210 Int iCUAddrInSlice = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU()); 1211 Int iCUAddrUpInSlice = iCUAddrInSlice - iNumCuInWidth; 1212 Int rx = uiCUAddr % iNumCuInWidth; 1213 Int ry = uiCUAddr / iNumCuInWidth; 1214 m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag()); 1215 } 1277 Int iNumCuInWidth = pcSlice->getAPS()->getSaoParam()->numCuInWidth; 1278 Int iCUAddrInSlice = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU()); 1279 Int iCUAddrUpInSlice = iCUAddrInSlice - iNumCuInWidth; 1280 Int rx = uiCUAddr % iNumCuInWidth; 1281 Int ry = uiCUAddr / iNumCuInWidth; 1282 m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag()); 1283 } 1284 #endif 1216 1285 #if ENC_DEC_TRACE 1217 1286 g_bJustDoIt = g_bEncDecTraceEnable; -
branches/HTM-6.2-dev1-LG/source/Lib/TLibEncoder/TEncTop.cpp
r384 r408 103 103 if (m_bUseSAO) 104 104 { 105 #if LGE_SAO_MIGRATION_D0091 106 m_cEncSAO.setSaoLcuBoundary(getSaoLcuBoundary()); 107 m_cEncSAO.setSaoLcuBasedOptimization(getSaoLcuBasedOptimization()); 108 #else 105 109 m_cEncSAO.setSaoInterleavingFlag(getSaoInterleavingFlag()); 110 #endif 106 111 m_cEncSAO.setMaxNumOffsetsPerPic(getMaxNumOffsetsPerPic()); 107 112 m_cEncSAO.create( getSourceWidth(), getSourceHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
Note: See TracChangeset for help on using the changeset viewer.