Changeset 593 in SHVCSoftware for branches/SHM-5.0-dev/source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp
- Timestamp:
- 2 Feb 2014, 04:51:29 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/SHM-5.0-dev/source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp
r540 r593 4 4 * granted under this license. 5 5 * 6 * Copyright (c) 2010-201 3, ITU/ISO/IEC6 * Copyright (c) 2010-2014, ITU/ISO/IEC 7 7 * All rights reserved. 8 8 * … … 44 44 //! \ingroup TLibCommon 45 45 //! \{ 46 #if HM_CLEANUP_SAO47 46 UInt g_saoMaxOffsetQVal[NUM_SAO_COMPONENTS]; 48 47 … … 698 697 return pBuf; 699 698 } 700 #else 701 702 SAOParam::~SAOParam() 703 { 704 for (Int i = 0 ; i<3; i++) 705 { 706 if (psSaoPart[i]) 707 { 708 delete [] psSaoPart[i]; 709 } 710 } 711 } 712 713 // ==================================================================================================================== 714 // Tables 715 // ==================================================================================================================== 716 717 TComSampleAdaptiveOffset::TComSampleAdaptiveOffset() 718 { 719 m_pClipTable = NULL; 720 m_pClipTableBase = NULL; 721 m_pChromaClipTable = NULL; 722 m_pChromaClipTableBase = NULL; 723 m_iOffsetBo = NULL; 724 m_iChromaOffsetBo = NULL; 725 m_lumaTableBo = NULL; 726 m_chromaTableBo = NULL; 727 m_iUpBuff1 = NULL; 728 m_iUpBuff2 = NULL; 729 m_iUpBufft = NULL; 730 ipSwap = NULL; 731 732 m_pTmpU1 = NULL; 733 m_pTmpU2 = NULL; 734 m_pTmpL1 = NULL; 735 m_pTmpL2 = NULL; 736 } 737 738 TComSampleAdaptiveOffset::~TComSampleAdaptiveOffset() 739 { 740 741 } 742 743 const Int TComSampleAdaptiveOffset::m_aiNumCulPartsLevel[5] = 744 { 745 1, //level 0 746 5, //level 1 747 21, //level 2 748 85, //level 3 749 341, //level 4 750 }; 751 752 const UInt TComSampleAdaptiveOffset::m_auiEoTable[9] = 753 { 754 1, //0 755 2, //1 756 0, //2 757 3, //3 758 4, //4 759 0, //5 760 0, //6 761 0, //7 762 0 763 }; 764 765 const Int TComSampleAdaptiveOffset::m_iNumClass[MAX_NUM_SAO_TYPE] = 766 { 767 SAO_EO_LEN, 768 SAO_EO_LEN, 769 SAO_EO_LEN, 770 SAO_EO_LEN, 771 SAO_BO_LEN 772 }; 773 774 const UInt TComSampleAdaptiveOffset::m_uiMaxDepth = SAO_MAX_DEPTH; 775 776 777 /** convert Level Row Col to Idx 778 * \param level, row, col 779 */ 780 Int TComSampleAdaptiveOffset::convertLevelRowCol2Idx(Int level, Int row, Int col) 781 { 782 Int idx; 783 if (level == 0) 784 { 785 idx = 0; 786 } 787 else if (level == 1) 788 { 789 idx = 1 + row*2 + col; 790 } 791 else if (level == 2) 792 { 793 idx = 5 + row*4 + col; 794 } 795 else if (level == 3) 796 { 797 idx = 21 + row*8 + col; 798 } 799 else // (level == 4) 800 { 801 idx = 85 + row*16 + col; 802 } 803 return idx; 804 } 805 806 /** create SampleAdaptiveOffset memory. 807 * \param 808 */ 809 Void TComSampleAdaptiveOffset::create( UInt uiSourceWidth, UInt uiSourceHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight ) 810 { 811 m_iPicWidth = uiSourceWidth; 812 m_iPicHeight = uiSourceHeight; 813 814 m_uiMaxCUWidth = uiMaxCUWidth; 815 m_uiMaxCUHeight = uiMaxCUHeight; 816 817 m_iNumCuInWidth = m_iPicWidth / m_uiMaxCUWidth; 818 m_iNumCuInWidth += ( m_iPicWidth % m_uiMaxCUWidth ) ? 1 : 0; 819 820 m_iNumCuInHeight = m_iPicHeight / m_uiMaxCUHeight; 821 m_iNumCuInHeight += ( m_iPicHeight % m_uiMaxCUHeight ) ? 1 : 0; 822 823 Int iMaxSplitLevelHeight = (Int)(logf((Float)m_iNumCuInHeight)/logf(2.0)); 824 Int iMaxSplitLevelWidth = (Int)(logf((Float)m_iNumCuInWidth )/logf(2.0)); 825 826 m_uiMaxSplitLevel = (iMaxSplitLevelHeight < iMaxSplitLevelWidth)?(iMaxSplitLevelHeight):(iMaxSplitLevelWidth); 827 m_uiMaxSplitLevel = (m_uiMaxSplitLevel< m_uiMaxDepth)?(m_uiMaxSplitLevel):(m_uiMaxDepth); 828 /* various structures are overloaded to store per component data. 829 * m_iNumTotalParts must allow for sufficient storage in any allocated arrays */ 830 m_iNumTotalParts = max(3,m_aiNumCulPartsLevel[m_uiMaxSplitLevel]); 831 832 UInt uiPixelRangeY = 1 << g_bitDepthY; 833 UInt uiBoRangeShiftY = g_bitDepthY - SAO_BO_BITS; 834 835 m_lumaTableBo = new Pel [uiPixelRangeY]; 836 for (Int k2=0; k2<uiPixelRangeY; k2++) 837 { 838 m_lumaTableBo[k2] = 1 + (k2>>uiBoRangeShiftY); 839 } 840 841 UInt uiPixelRangeC = 1 << g_bitDepthC; 842 UInt uiBoRangeShiftC = g_bitDepthC - SAO_BO_BITS; 843 844 m_chromaTableBo = new Pel [uiPixelRangeC]; 845 for (Int k2=0; k2<uiPixelRangeC; k2++) 846 { 847 m_chromaTableBo[k2] = 1 + (k2>>uiBoRangeShiftC); 848 } 849 850 m_iUpBuff1 = new Int[m_iPicWidth+2]; 851 m_iUpBuff2 = new Int[m_iPicWidth+2]; 852 m_iUpBufft = new Int[m_iPicWidth+2]; 853 854 m_iUpBuff1++; 855 m_iUpBuff2++; 856 m_iUpBufft++; 857 Pel i; 858 859 UInt uiMaxY = (1 << g_bitDepthY) - 1;; 860 UInt uiMinY = 0; 861 862 Int iCRangeExt = uiMaxY>>1; 863 864 m_pClipTableBase = new Pel[uiMaxY+2*iCRangeExt]; 865 m_iOffsetBo = new Int[uiMaxY+2*iCRangeExt]; 866 867 for(i=0;i<(uiMinY+iCRangeExt);i++) 868 { 869 m_pClipTableBase[i] = uiMinY; 870 } 871 872 for(i=uiMinY+iCRangeExt;i<(uiMaxY+ iCRangeExt);i++) 873 { 874 m_pClipTableBase[i] = i-iCRangeExt; 875 } 876 877 for(i=uiMaxY+iCRangeExt;i<(uiMaxY+2*iCRangeExt);i++) 878 { 879 m_pClipTableBase[i] = uiMaxY; 880 } 881 882 m_pClipTable = &(m_pClipTableBase[iCRangeExt]); 883 884 UInt uiMaxC = (1 << g_bitDepthC) - 1; 885 UInt uiMinC = 0; 886 887 Int iCRangeExtC = uiMaxC>>1; 888 889 m_pChromaClipTableBase = new Pel[uiMaxC+2*iCRangeExtC]; 890 m_iChromaOffsetBo = new Int[uiMaxC+2*iCRangeExtC]; 891 892 for(i=0;i<(uiMinC+iCRangeExtC);i++) 893 { 894 m_pChromaClipTableBase[i] = uiMinC; 895 } 896 897 for(i=uiMinC+iCRangeExtC;i<(uiMaxC+ iCRangeExtC);i++) 898 { 899 m_pChromaClipTableBase[i] = i-iCRangeExtC; 900 } 901 902 for(i=uiMaxC+iCRangeExtC;i<(uiMaxC+2*iCRangeExtC);i++) 903 { 904 m_pChromaClipTableBase[i] = uiMaxC; 905 } 906 907 m_pChromaClipTable = &(m_pChromaClipTableBase[iCRangeExtC]); 908 909 m_pTmpL1 = new Pel [m_uiMaxCUHeight+1]; 910 m_pTmpL2 = new Pel [m_uiMaxCUHeight+1]; 911 m_pTmpU1 = new Pel [m_iPicWidth]; 912 m_pTmpU2 = new Pel [m_iPicWidth]; 913 } 914 915 /** destroy SampleAdaptiveOffset memory. 916 * \param 917 */ 918 Void TComSampleAdaptiveOffset::destroy() 919 { 920 if (m_pClipTableBase) 921 { 922 delete [] m_pClipTableBase; m_pClipTableBase = NULL; 923 } 924 if (m_iOffsetBo) 925 { 926 delete [] m_iOffsetBo; m_iOffsetBo = NULL; 927 } 928 if (m_lumaTableBo) 929 { 930 delete[] m_lumaTableBo; m_lumaTableBo = NULL; 931 } 932 933 if (m_pChromaClipTableBase) 934 { 935 delete [] m_pChromaClipTableBase; m_pChromaClipTableBase = NULL; 936 } 937 if (m_iChromaOffsetBo) 938 { 939 delete [] m_iChromaOffsetBo; m_iChromaOffsetBo = NULL; 940 } 941 if (m_chromaTableBo) 942 { 943 delete[] m_chromaTableBo; m_chromaTableBo = NULL; 944 } 945 946 if (m_iUpBuff1) 947 { 948 m_iUpBuff1--; 949 delete [] m_iUpBuff1; m_iUpBuff1 = NULL; 950 } 951 if (m_iUpBuff2) 952 { 953 m_iUpBuff2--; 954 delete [] m_iUpBuff2; m_iUpBuff2 = NULL; 955 } 956 if (m_iUpBufft) 957 { 958 m_iUpBufft--; 959 delete [] m_iUpBufft; m_iUpBufft = NULL; 960 } 961 if (m_pTmpL1) 962 { 963 delete [] m_pTmpL1; m_pTmpL1 = NULL; 964 } 965 if (m_pTmpL2) 966 { 967 delete [] m_pTmpL2; m_pTmpL2 = NULL; 968 } 969 if (m_pTmpU1) 970 { 971 delete [] m_pTmpU1; m_pTmpU1 = NULL; 972 } 973 if (m_pTmpU2) 974 { 975 delete [] m_pTmpU2; m_pTmpU2 = NULL; 976 } 977 } 978 979 /** allocate memory for SAO parameters 980 * \param *pcSaoParam 981 */ 982 Void TComSampleAdaptiveOffset::allocSaoParam(SAOParam *pcSaoParam) 983 { 984 pcSaoParam->iMaxSplitLevel = m_uiMaxSplitLevel; 985 pcSaoParam->psSaoPart[0] = new SAOQTPart[ m_aiNumCulPartsLevel[pcSaoParam->iMaxSplitLevel] ]; 986 initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1, 0, m_iNumCuInHeight-1,0); 987 pcSaoParam->psSaoPart[1] = new SAOQTPart[ m_aiNumCulPartsLevel[pcSaoParam->iMaxSplitLevel] ]; 988 pcSaoParam->psSaoPart[2] = new SAOQTPart[ m_aiNumCulPartsLevel[pcSaoParam->iMaxSplitLevel] ]; 989 initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1, 0, m_iNumCuInHeight-1,1); 990 initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1, 0, m_iNumCuInHeight-1,2); 991 pcSaoParam->numCuInWidth = m_iNumCuInWidth; 992 pcSaoParam->numCuInHeight = m_iNumCuInHeight; 993 pcSaoParam->saoLcuParam[0] = new SaoLcuParam [m_iNumCuInHeight*m_iNumCuInWidth]; 994 pcSaoParam->saoLcuParam[1] = new SaoLcuParam [m_iNumCuInHeight*m_iNumCuInWidth]; 995 pcSaoParam->saoLcuParam[2] = new SaoLcuParam [m_iNumCuInHeight*m_iNumCuInWidth]; 996 } 997 998 /** initialize SAO parameters 999 * \param *pcSaoParam, iPartLevel, iPartRow, iPartCol, iParentPartIdx, StartCUX, EndCUX, StartCUY, EndCUY, iYCbCr 1000 */ 1001 Void TComSampleAdaptiveOffset::initSAOParam(SAOParam *pcSaoParam, Int iPartLevel, Int iPartRow, Int iPartCol, Int iParentPartIdx, Int StartCUX, Int EndCUX, Int StartCUY, Int EndCUY, Int iYCbCr) 1002 { 1003 Int j; 1004 Int iPartIdx = convertLevelRowCol2Idx(iPartLevel, iPartRow, iPartCol); 1005 1006 SAOQTPart* pSaoPart; 1007 1008 pSaoPart = &(pcSaoParam->psSaoPart[iYCbCr][iPartIdx]); 1009 1010 pSaoPart->PartIdx = iPartIdx; 1011 pSaoPart->PartLevel = iPartLevel; 1012 pSaoPart->PartRow = iPartRow; 1013 pSaoPart->PartCol = iPartCol; 1014 1015 pSaoPart->StartCUX = StartCUX; 1016 pSaoPart->EndCUX = EndCUX; 1017 pSaoPart->StartCUY = StartCUY; 1018 pSaoPart->EndCUY = EndCUY; 1019 1020 pSaoPart->UpPartIdx = iParentPartIdx; 1021 pSaoPart->iBestType = -1; 1022 pSaoPart->iLength = 0; 1023 1024 pSaoPart->subTypeIdx = 0; 1025 1026 for (j=0;j<MAX_NUM_SAO_OFFSETS;j++) 1027 { 1028 pSaoPart->iOffset[j] = 0; 1029 } 1030 1031 if(pSaoPart->PartLevel != m_uiMaxSplitLevel) 1032 { 1033 Int DownLevel = (iPartLevel+1 ); 1034 Int DownRowStart = (iPartRow << 1); 1035 Int DownColStart = (iPartCol << 1); 1036 1037 Int iDownRowIdx, iDownColIdx; 1038 Int NumCUWidth, NumCUHeight; 1039 Int NumCULeft; 1040 Int NumCUTop; 1041 1042 Int DownStartCUX, DownStartCUY; 1043 Int DownEndCUX, DownEndCUY; 1044 1045 NumCUWidth = EndCUX - StartCUX +1; 1046 NumCUHeight = EndCUY - StartCUY +1; 1047 NumCULeft = (NumCUWidth >> 1); 1048 NumCUTop = (NumCUHeight >> 1); 1049 1050 DownStartCUX= StartCUX; 1051 DownEndCUX = DownStartCUX + NumCULeft - 1; 1052 DownStartCUY= StartCUY; 1053 DownEndCUY = DownStartCUY + NumCUTop - 1; 1054 iDownRowIdx = DownRowStart + 0; 1055 iDownColIdx = DownColStart + 0; 1056 1057 pSaoPart->DownPartsIdx[0]= convertLevelRowCol2Idx(DownLevel, iDownRowIdx, iDownColIdx); 1058 1059 initSAOParam(pcSaoParam, DownLevel, iDownRowIdx, iDownColIdx, iPartIdx, DownStartCUX, DownEndCUX, DownStartCUY, DownEndCUY, iYCbCr); 1060 1061 DownStartCUX = StartCUX + NumCULeft; 1062 DownEndCUX = EndCUX; 1063 DownStartCUY = StartCUY; 1064 DownEndCUY = DownStartCUY + NumCUTop -1; 1065 iDownRowIdx = DownRowStart + 0; 1066 iDownColIdx = DownColStart + 1; 1067 1068 pSaoPart->DownPartsIdx[1] = convertLevelRowCol2Idx(DownLevel, iDownRowIdx, iDownColIdx); 1069 1070 initSAOParam(pcSaoParam, DownLevel, iDownRowIdx, iDownColIdx, iPartIdx, DownStartCUX, DownEndCUX, DownStartCUY, DownEndCUY, iYCbCr); 1071 1072 DownStartCUX = StartCUX; 1073 DownEndCUX = DownStartCUX + NumCULeft -1; 1074 DownStartCUY = StartCUY + NumCUTop; 1075 DownEndCUY = EndCUY; 1076 iDownRowIdx = DownRowStart + 1; 1077 iDownColIdx = DownColStart + 0; 1078 1079 pSaoPart->DownPartsIdx[2] = convertLevelRowCol2Idx(DownLevel, iDownRowIdx, iDownColIdx); 1080 1081 initSAOParam(pcSaoParam, DownLevel, iDownRowIdx, iDownColIdx, iPartIdx, DownStartCUX, DownEndCUX, DownStartCUY, DownEndCUY, iYCbCr); 1082 1083 DownStartCUX = StartCUX+ NumCULeft; 1084 DownEndCUX = EndCUX; 1085 DownStartCUY = StartCUY + NumCUTop; 1086 DownEndCUY = EndCUY; 1087 iDownRowIdx = DownRowStart + 1; 1088 iDownColIdx = DownColStart + 1; 1089 1090 pSaoPart->DownPartsIdx[3] = convertLevelRowCol2Idx(DownLevel, iDownRowIdx, iDownColIdx); 1091 1092 initSAOParam(pcSaoParam, DownLevel, iDownRowIdx, iDownColIdx, iPartIdx,DownStartCUX, DownEndCUX, DownStartCUY, DownEndCUY, iYCbCr); 1093 } 1094 else 1095 { 1096 pSaoPart->DownPartsIdx[0]=pSaoPart->DownPartsIdx[1]= pSaoPart->DownPartsIdx[2]= pSaoPart->DownPartsIdx[3]= -1; 1097 } 1098 } 1099 1100 /** free memory of SAO parameters 1101 * \param pcSaoParam 1102 */ 1103 Void TComSampleAdaptiveOffset::freeSaoParam(SAOParam *pcSaoParam) 1104 { 1105 delete [] pcSaoParam->psSaoPart[0]; 1106 delete [] pcSaoParam->psSaoPart[1]; 1107 delete [] pcSaoParam->psSaoPart[2]; 1108 pcSaoParam->psSaoPart[0] = 0; 1109 pcSaoParam->psSaoPart[1] = 0; 1110 pcSaoParam->psSaoPart[2] = 0; 1111 if( pcSaoParam->saoLcuParam[0]) 1112 { 1113 delete [] pcSaoParam->saoLcuParam[0]; pcSaoParam->saoLcuParam[0] = NULL; 1114 } 1115 if( pcSaoParam->saoLcuParam[1]) 1116 { 1117 delete [] pcSaoParam->saoLcuParam[1]; pcSaoParam->saoLcuParam[1] = NULL; 1118 } 1119 if( pcSaoParam->saoLcuParam[2]) 1120 { 1121 delete [] pcSaoParam->saoLcuParam[2]; pcSaoParam->saoLcuParam[2] = NULL; 1122 } 1123 } 1124 1125 /** reset SAO parameters 1126 * \param pcSaoParam 1127 */ 1128 Void TComSampleAdaptiveOffset::resetSAOParam(SAOParam *pcSaoParam) 1129 { 1130 Int iNumComponet = 3; 1131 for(Int c=0; c<iNumComponet; c++) 1132 { 1133 if (c<2) 1134 { 1135 pcSaoParam->bSaoFlag[c] = 0; 1136 } 1137 for(Int i=0; i< m_aiNumCulPartsLevel[m_uiMaxSplitLevel]; i++) 1138 { 1139 pcSaoParam->psSaoPart[c][i].iBestType = -1; 1140 pcSaoParam->psSaoPart[c][i].iLength = 0; 1141 pcSaoParam->psSaoPart[c][i].bSplit = false; 1142 pcSaoParam->psSaoPart[c][i].bProcessed = false; 1143 pcSaoParam->psSaoPart[c][i].dMinCost = MAX_DOUBLE; 1144 pcSaoParam->psSaoPart[c][i].iMinDist = MAX_INT; 1145 pcSaoParam->psSaoPart[c][i].iMinRate = MAX_INT; 1146 pcSaoParam->psSaoPart[c][i].subTypeIdx = 0; 1147 for (Int j=0;j<MAX_NUM_SAO_OFFSETS;j++) 1148 { 1149 pcSaoParam->psSaoPart[c][i].iOffset[j] = 0; 1150 pcSaoParam->psSaoPart[c][i].iOffset[j] = 0; 1151 pcSaoParam->psSaoPart[c][i].iOffset[j] = 0; 1152 } 1153 } 1154 pcSaoParam->oneUnitFlag[0] = 0; 1155 pcSaoParam->oneUnitFlag[1] = 0; 1156 pcSaoParam->oneUnitFlag[2] = 0; 1157 resetLcuPart(pcSaoParam->saoLcuParam[0]); 1158 resetLcuPart(pcSaoParam->saoLcuParam[1]); 1159 resetLcuPart(pcSaoParam->saoLcuParam[2]); 1160 } 1161 } 1162 1163 /** get the sign of input variable 1164 * \param x 1165 */ 1166 inline Int xSign(Int x) 1167 { 1168 return ((x >> 31) | ((Int)( (((UInt) -x)) >> 31))); 1169 } 1170 1171 /** initialize variables for SAO process 1172 * \param pcPic picture data pointer 1173 */ 1174 Void TComSampleAdaptiveOffset::createPicSaoInfo(TComPic* pcPic) 1175 { 1176 m_pcPic = pcPic; 1177 m_bUseNIF = ( pcPic->getIndependentSliceBoundaryForNDBFilter() || pcPic->getIndependentTileBoundaryForNDBFilter() ); 1178 if(m_bUseNIF) 1179 { 1180 m_pcYuvTmp = pcPic->getYuvPicBufferForIndependentBoundaryProcessing(); 1181 } 1182 } 1183 1184 Void TComSampleAdaptiveOffset::destroyPicSaoInfo() 1185 { 1186 1187 } 1188 1189 /** sample adaptive offset process for one LCU 1190 * \param iAddr, iSaoType, iYCbCr 1191 */ 1192 Void TComSampleAdaptiveOffset::processSaoCu(Int iAddr, Int iSaoType, Int iYCbCr) 1193 { 1194 if(!m_bUseNIF) 1195 { 1196 processSaoCuOrg( iAddr, iSaoType, iYCbCr); 1197 } 1198 else 1199 { 1200 Int isChroma = (iYCbCr != 0)? 1:0; 1201 Int stride = (iYCbCr != 0)?(m_pcPic->getCStride()):(m_pcPic->getStride()); 1202 Pel* pPicRest = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr); 1203 Pel* pPicDec = getPicYuvAddr(m_pcYuvTmp, iYCbCr); 1204 1205 std::vector<NDBFBlockInfo>& vFilterBlocks = *(m_pcPic->getCU(iAddr)->getNDBFilterBlocks()); 1206 1207 //variables 1208 UInt xPos, yPos, width, height; 1209 Bool* pbBorderAvail; 1210 UInt posOffset; 1211 1212 for(Int i=0; i< vFilterBlocks.size(); i++) 1213 { 1214 xPos = vFilterBlocks[i].posX >> isChroma; 1215 yPos = vFilterBlocks[i].posY >> isChroma; 1216 width = vFilterBlocks[i].width >> isChroma; 1217 height = vFilterBlocks[i].height >> isChroma; 1218 pbBorderAvail = vFilterBlocks[i].isBorderAvailable; 1219 1220 posOffset = (yPos* stride) + xPos; 1221 1222 processSaoBlock(pPicDec+ posOffset, pPicRest+ posOffset, stride, iSaoType, width, height, pbBorderAvail, iYCbCr); 1223 } 1224 } 1225 } 1226 1227 /** Perform SAO for non-cross-slice or non-cross-tile process 1228 * \param pDec to-be-filtered block buffer pointer 1229 * \param pRest filtered block buffer pointer 1230 * \param stride picture buffer stride 1231 * \param saoType SAO offset type 1232 * \param xPos x coordinate 1233 * \param yPos y coordinate 1234 * \param width block width 1235 * \param height block height 1236 * \param pbBorderAvail availabilities of block border pixels 1237 */ 1238 Void TComSampleAdaptiveOffset::processSaoBlock(Pel* pDec, Pel* pRest, Int stride, Int saoType, UInt width, UInt height, Bool* pbBorderAvail, Int iYCbCr) 1239 { 1240 //variables 1241 Int startX, startY, endX, endY, x, y; 1242 Int signLeft,signRight,signDown,signDown1; 1243 UInt edgeType; 1244 Pel *pClipTbl = (iYCbCr==0)?m_pClipTable:m_pChromaClipTable; 1245 Int *pOffsetBo = (iYCbCr==0)?m_iOffsetBo: m_iChromaOffsetBo; 1246 1247 switch (saoType) 1248 { 1249 case SAO_EO_0: // dir: - 1250 { 1251 1252 startX = (pbBorderAvail[SGU_L]) ? 0 : 1; 1253 endX = (pbBorderAvail[SGU_R]) ? width : (width -1); 1254 for (y=0; y< height; y++) 1255 { 1256 signLeft = xSign(pDec[startX] - pDec[startX-1]); 1257 for (x=startX; x< endX; x++) 1258 { 1259 signRight = xSign(pDec[x] - pDec[x+1]); 1260 edgeType = signRight + signLeft + 2; 1261 signLeft = -signRight; 1262 1263 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1264 } 1265 pDec += stride; 1266 pRest += stride; 1267 } 1268 break; 1269 } 1270 case SAO_EO_1: // dir: | 1271 { 1272 startY = (pbBorderAvail[SGU_T]) ? 0 : 1; 1273 endY = (pbBorderAvail[SGU_B]) ? height : height-1; 1274 if (!pbBorderAvail[SGU_T]) 1275 { 1276 pDec += stride; 1277 pRest += stride; 1278 } 1279 for (x=0; x< width; x++) 1280 { 1281 m_iUpBuff1[x] = xSign(pDec[x] - pDec[x-stride]); 1282 } 1283 for (y=startY; y<endY; y++) 1284 { 1285 for (x=0; x< width; x++) 1286 { 1287 signDown = xSign(pDec[x] - pDec[x+stride]); 1288 edgeType = signDown + m_iUpBuff1[x] + 2; 1289 m_iUpBuff1[x]= -signDown; 1290 1291 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1292 } 1293 pDec += stride; 1294 pRest += stride; 1295 } 1296 break; 1297 } 1298 case SAO_EO_2: // dir: 135 1299 { 1300 Int posShift= stride + 1; 1301 1302 startX = (pbBorderAvail[SGU_L]) ? 0 : 1 ; 1303 endX = (pbBorderAvail[SGU_R]) ? width : (width-1); 1304 1305 //prepare 2nd line upper sign 1306 pDec += stride; 1307 for (x=startX; x< endX+1; x++) 1308 { 1309 m_iUpBuff1[x] = xSign(pDec[x] - pDec[x- posShift]); 1310 } 1311 1312 //1st line 1313 pDec -= stride; 1314 if(pbBorderAvail[SGU_TL]) 1315 { 1316 x= 0; 1317 edgeType = xSign(pDec[x] - pDec[x- posShift]) - m_iUpBuff1[x+1] + 2; 1318 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1319 1320 } 1321 if(pbBorderAvail[SGU_T]) 1322 { 1323 for(x= 1; x< endX; x++) 1324 { 1325 edgeType = xSign(pDec[x] - pDec[x- posShift]) - m_iUpBuff1[x+1] + 2; 1326 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1327 } 1328 } 1329 pDec += stride; 1330 pRest += stride; 1331 1332 1333 //middle lines 1334 for (y= 1; y< height-1; y++) 1335 { 1336 for (x=startX; x<endX; x++) 1337 { 1338 signDown1 = xSign(pDec[x] - pDec[x+ posShift]) ; 1339 edgeType = signDown1 + m_iUpBuff1[x] + 2; 1340 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1341 1342 m_iUpBufft[x+1] = -signDown1; 1343 } 1344 m_iUpBufft[startX] = xSign(pDec[stride+startX] - pDec[startX-1]); 1345 1346 ipSwap = m_iUpBuff1; 1347 m_iUpBuff1 = m_iUpBufft; 1348 m_iUpBufft = ipSwap; 1349 1350 pDec += stride; 1351 pRest += stride; 1352 } 1353 1354 //last line 1355 if(pbBorderAvail[SGU_B]) 1356 { 1357 for(x= startX; x< width-1; x++) 1358 { 1359 edgeType = xSign(pDec[x] - pDec[x+ posShift]) + m_iUpBuff1[x] + 2; 1360 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1361 } 1362 } 1363 if(pbBorderAvail[SGU_BR]) 1364 { 1365 x= width -1; 1366 edgeType = xSign(pDec[x] - pDec[x+ posShift]) + m_iUpBuff1[x] + 2; 1367 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1368 } 1369 break; 1370 } 1371 case SAO_EO_3: // dir: 45 1372 { 1373 Int posShift = stride - 1; 1374 startX = (pbBorderAvail[SGU_L]) ? 0 : 1; 1375 endX = (pbBorderAvail[SGU_R]) ? width : (width -1); 1376 1377 //prepare 2nd line upper sign 1378 pDec += stride; 1379 for (x=startX-1; x< endX; x++) 1380 { 1381 m_iUpBuff1[x] = xSign(pDec[x] - pDec[x- posShift]); 1382 } 1383 1384 1385 //first line 1386 pDec -= stride; 1387 if(pbBorderAvail[SGU_T]) 1388 { 1389 for(x= startX; x< width -1; x++) 1390 { 1391 edgeType = xSign(pDec[x] - pDec[x- posShift]) -m_iUpBuff1[x-1] + 2; 1392 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1393 } 1394 } 1395 if(pbBorderAvail[SGU_TR]) 1396 { 1397 x= width-1; 1398 edgeType = xSign(pDec[x] - pDec[x- posShift]) -m_iUpBuff1[x-1] + 2; 1399 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1400 } 1401 pDec += stride; 1402 pRest += stride; 1403 1404 //middle lines 1405 for (y= 1; y< height-1; y++) 1406 { 1407 for(x= startX; x< endX; x++) 1408 { 1409 signDown1 = xSign(pDec[x] - pDec[x+ posShift]) ; 1410 edgeType = signDown1 + m_iUpBuff1[x] + 2; 1411 1412 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1413 m_iUpBuff1[x-1] = -signDown1; 1414 } 1415 m_iUpBuff1[endX-1] = xSign(pDec[endX-1 + stride] - pDec[endX]); 1416 1417 pDec += stride; 1418 pRest += stride; 1419 } 1420 1421 //last line 1422 if(pbBorderAvail[SGU_BL]) 1423 { 1424 x= 0; 1425 edgeType = xSign(pDec[x] - pDec[x+ posShift]) + m_iUpBuff1[x] + 2; 1426 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1427 1428 } 1429 if(pbBorderAvail[SGU_B]) 1430 { 1431 for(x= 1; x< endX; x++) 1432 { 1433 edgeType = xSign(pDec[x] - pDec[x+ posShift]) + m_iUpBuff1[x] + 2; 1434 pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]]; 1435 } 1436 } 1437 break; 1438 } 1439 case SAO_BO: 1440 { 1441 for (y=0; y< height; y++) 1442 { 1443 for (x=0; x< width; x++) 1444 { 1445 pRest[x] = pOffsetBo[pDec[x]]; 1446 } 1447 pRest += stride; 1448 pDec += stride; 1449 } 1450 break; 1451 } 1452 default: break; 1453 } 1454 1455 } 1456 1457 /** sample adaptive offset process for one LCU crossing LCU boundary 1458 * \param iAddr, iSaoType, iYCbCr 1459 */ 1460 Void TComSampleAdaptiveOffset::processSaoCuOrg(Int iAddr, Int iSaoType, Int iYCbCr) 1461 { 1462 Int x,y; 1463 TComDataCU *pTmpCu = m_pcPic->getCU(iAddr); 1464 Pel* pRec; 1465 Int iStride; 1466 Int iLcuWidth = m_uiMaxCUWidth; 1467 Int iLcuHeight = m_uiMaxCUHeight; 1468 UInt uiLPelX = pTmpCu->getCUPelX(); 1469 UInt uiTPelY = pTmpCu->getCUPelY(); 1470 UInt uiRPelX; 1471 UInt uiBPelY; 1472 Int iSignLeft; 1473 Int iSignRight; 1474 Int iSignDown; 1475 Int iSignDown1; 1476 Int iSignDown2; 1477 UInt uiEdgeType; 1478 Int iPicWidthTmp; 1479 Int iPicHeightTmp; 1480 Int iStartX; 1481 Int iStartY; 1482 Int iEndX; 1483 Int iEndY; 1484 Int iIsChroma = (iYCbCr!=0)? 1:0; 1485 Int iShift; 1486 Int iCuHeightTmp; 1487 Pel *pTmpLSwap; 1488 Pel *pTmpL; 1489 Pel *pTmpU; 1490 Pel *pClipTbl = NULL; 1491 Int *pOffsetBo = NULL; 1492 1493 iPicWidthTmp = m_iPicWidth >> iIsChroma; 1494 iPicHeightTmp = m_iPicHeight >> iIsChroma; 1495 iLcuWidth = iLcuWidth >> iIsChroma; 1496 iLcuHeight = iLcuHeight >> iIsChroma; 1497 uiLPelX = uiLPelX >> iIsChroma; 1498 uiTPelY = uiTPelY >> iIsChroma; 1499 uiRPelX = uiLPelX + iLcuWidth ; 1500 uiBPelY = uiTPelY + iLcuHeight ; 1501 uiRPelX = uiRPelX > iPicWidthTmp ? iPicWidthTmp : uiRPelX; 1502 uiBPelY = uiBPelY > iPicHeightTmp ? iPicHeightTmp : uiBPelY; 1503 iLcuWidth = uiRPelX - uiLPelX; 1504 iLcuHeight = uiBPelY - uiTPelY; 1505 1506 if(pTmpCu->getPic()==0) 1507 { 1508 return; 1509 } 1510 if (iYCbCr == 0) 1511 { 1512 pRec = m_pcPic->getPicYuvRec()->getLumaAddr(iAddr); 1513 iStride = m_pcPic->getStride(); 1514 } 1515 else if (iYCbCr == 1) 1516 { 1517 pRec = m_pcPic->getPicYuvRec()->getCbAddr(iAddr); 1518 iStride = m_pcPic->getCStride(); 1519 } 1520 else 1521 { 1522 pRec = m_pcPic->getPicYuvRec()->getCrAddr(iAddr); 1523 iStride = m_pcPic->getCStride(); 1524 } 1525 1526 // if (iSaoType!=SAO_BO_0 || iSaoType!=SAO_BO_1) 1527 { 1528 iCuHeightTmp = (m_uiMaxCUHeight >> iIsChroma); 1529 iShift = (m_uiMaxCUWidth>> iIsChroma)-1; 1530 for (Int i=0;i<iCuHeightTmp+1;i++) 1531 { 1532 m_pTmpL2[i] = pRec[iShift]; 1533 pRec += iStride; 1534 } 1535 pRec -= (iStride*(iCuHeightTmp+1)); 1536 1537 pTmpL = m_pTmpL1; 1538 pTmpU = &(m_pTmpU1[uiLPelX]); 1539 } 1540 1541 pClipTbl = (iYCbCr==0)? m_pClipTable:m_pChromaClipTable; 1542 pOffsetBo = (iYCbCr==0)? m_iOffsetBo:m_iChromaOffsetBo; 1543 1544 switch (iSaoType) 1545 { 1546 case SAO_EO_0: // dir: - 1547 { 1548 iStartX = (uiLPelX == 0) ? 1 : 0; 1549 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth; 1550 for (y=0; y<iLcuHeight; y++) 1551 { 1552 iSignLeft = xSign(pRec[iStartX] - pTmpL[y]); 1553 for (x=iStartX; x< iEndX; x++) 1554 { 1555 iSignRight = xSign(pRec[x] - pRec[x+1]); 1556 uiEdgeType = iSignRight + iSignLeft + 2; 1557 iSignLeft = -iSignRight; 1558 1559 pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]]; 1560 } 1561 pRec += iStride; 1562 } 1563 break; 1564 } 1565 case SAO_EO_1: // dir: | 1566 { 1567 iStartY = (uiTPelY == 0) ? 1 : 0; 1568 iEndY = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight; 1569 if (uiTPelY == 0) 1570 { 1571 pRec += iStride; 1572 } 1573 for (x=0; x< iLcuWidth; x++) 1574 { 1575 m_iUpBuff1[x] = xSign(pRec[x] - pTmpU[x]); 1576 } 1577 for (y=iStartY; y<iEndY; y++) 1578 { 1579 for (x=0; x<iLcuWidth; x++) 1580 { 1581 iSignDown = xSign(pRec[x] - pRec[x+iStride]); 1582 uiEdgeType = iSignDown + m_iUpBuff1[x] + 2; 1583 m_iUpBuff1[x]= -iSignDown; 1584 1585 pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]]; 1586 } 1587 pRec += iStride; 1588 } 1589 break; 1590 } 1591 case SAO_EO_2: // dir: 135 1592 { 1593 iStartX = (uiLPelX == 0) ? 1 : 0; 1594 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth; 1595 1596 iStartY = (uiTPelY == 0) ? 1 : 0; 1597 iEndY = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight; 1598 1599 if (uiTPelY == 0) 1600 { 1601 pRec += iStride; 1602 } 1603 1604 for (x=iStartX; x<iEndX; x++) 1605 { 1606 m_iUpBuff1[x] = xSign(pRec[x] - pTmpU[x-1]); 1607 } 1608 for (y=iStartY; y<iEndY; y++) 1609 { 1610 iSignDown2 = xSign(pRec[iStride+iStartX] - pTmpL[y]); 1611 for (x=iStartX; x<iEndX; x++) 1612 { 1613 iSignDown1 = xSign(pRec[x] - pRec[x+iStride+1]) ; 1614 uiEdgeType = iSignDown1 + m_iUpBuff1[x] + 2; 1615 m_iUpBufft[x+1] = -iSignDown1; 1616 pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]]; 1617 } 1618 m_iUpBufft[iStartX] = iSignDown2; 1619 1620 ipSwap = m_iUpBuff1; 1621 m_iUpBuff1 = m_iUpBufft; 1622 m_iUpBufft = ipSwap; 1623 1624 pRec += iStride; 1625 } 1626 break; 1627 } 1628 case SAO_EO_3: // dir: 45 1629 { 1630 iStartX = (uiLPelX == 0) ? 1 : 0; 1631 iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth; 1632 1633 iStartY = (uiTPelY == 0) ? 1 : 0; 1634 iEndY = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight; 1635 1636 if (iStartY == 1) 1637 { 1638 pRec += iStride; 1639 } 1640 1641 for (x=iStartX-1; x<iEndX; x++) 1642 { 1643 m_iUpBuff1[x] = xSign(pRec[x] - pTmpU[x+1]); 1644 } 1645 for (y=iStartY; y<iEndY; y++) 1646 { 1647 x=iStartX; 1648 iSignDown1 = xSign(pRec[x] - pTmpL[y+1]) ; 1649 uiEdgeType = iSignDown1 + m_iUpBuff1[x] + 2; 1650 m_iUpBuff1[x-1] = -iSignDown1; 1651 pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]]; 1652 for (x=iStartX+1; x<iEndX; x++) 1653 { 1654 iSignDown1 = xSign(pRec[x] - pRec[x+iStride-1]) ; 1655 uiEdgeType = iSignDown1 + m_iUpBuff1[x] + 2; 1656 m_iUpBuff1[x-1] = -iSignDown1; 1657 pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]]; 1658 } 1659 m_iUpBuff1[iEndX-1] = xSign(pRec[iEndX-1 + iStride] - pRec[iEndX]); 1660 1661 pRec += iStride; 1662 } 1663 break; 1664 } 1665 case SAO_BO: 1666 { 1667 for (y=0; y<iLcuHeight; y++) 1668 { 1669 for (x=0; x<iLcuWidth; x++) 1670 { 1671 pRec[x] = pOffsetBo[pRec[x]]; 1672 } 1673 pRec += iStride; 1674 } 1675 break; 1676 } 1677 default: break; 1678 } 1679 // if (iSaoType!=SAO_BO_0 || iSaoType!=SAO_BO_1) 1680 { 1681 pTmpLSwap = m_pTmpL1; 1682 m_pTmpL1 = m_pTmpL2; 1683 m_pTmpL2 = pTmpLSwap; 1684 } 1685 } 1686 /** Sample adaptive offset process 1687 * \param pcPic, pcSaoParam 1688 */ 1689 Void TComSampleAdaptiveOffset::SAOProcess(SAOParam* pcSaoParam) 1690 { 1691 { 1692 m_uiSaoBitIncreaseY = max(g_bitDepthY - 10, 0); 1693 m_uiSaoBitIncreaseC = max(g_bitDepthC - 10, 0); 1694 1695 if(m_bUseNIF) 1696 { 1697 m_pcPic->getPicYuvRec()->copyToPic(m_pcYuvTmp); 1698 } 1699 if (m_saoLcuBasedOptimization) 1700 { 1701 pcSaoParam->oneUnitFlag[0] = 0; 1702 pcSaoParam->oneUnitFlag[1] = 0; 1703 pcSaoParam->oneUnitFlag[2] = 0; 1704 } 1705 Int iY = 0; 1706 { 1707 processSaoUnitAll( pcSaoParam->saoLcuParam[iY], pcSaoParam->oneUnitFlag[iY], iY); 1708 } 1709 { 1710 processSaoUnitAll( pcSaoParam->saoLcuParam[1], pcSaoParam->oneUnitFlag[1], 1);//Cb 1711 processSaoUnitAll( pcSaoParam->saoLcuParam[2], pcSaoParam->oneUnitFlag[2], 2);//Cr 1712 } 1713 m_pcPic = NULL; 1714 } 1715 } 1716 1717 Pel* TComSampleAdaptiveOffset::getPicYuvAddr(TComPicYuv* pcPicYuv, Int iYCbCr, Int iAddr) 1718 { 1719 switch (iYCbCr) 1720 { 1721 case 0: 1722 return pcPicYuv->getLumaAddr(iAddr); 1723 break; 1724 case 1: 1725 return pcPicYuv->getCbAddr(iAddr); 1726 break; 1727 case 2: 1728 return pcPicYuv->getCrAddr(iAddr); 1729 break; 1730 default: 1731 return NULL; 1732 break; 1733 } 1734 } 1735 /** Process SAO all units 1736 * \param saoLcuParam SAO LCU parameters 1737 * \param oneUnitFlag one unit flag 1738 * \param yCbCr color componet index 1739 */ 1740 Void TComSampleAdaptiveOffset::processSaoUnitAll(SaoLcuParam* saoLcuParam, Bool oneUnitFlag, Int yCbCr) 1741 { 1742 Pel *pRec; 1743 Int picWidthTmp; 1744 1745 if (yCbCr == 0) 1746 { 1747 pRec = m_pcPic->getPicYuvRec()->getLumaAddr(); 1748 picWidthTmp = m_iPicWidth; 1749 } 1750 else if (yCbCr == 1) 1751 { 1752 pRec = m_pcPic->getPicYuvRec()->getCbAddr(); 1753 picWidthTmp = m_iPicWidth>>1; 1754 } 1755 else 1756 { 1757 pRec = m_pcPic->getPicYuvRec()->getCrAddr(); 1758 picWidthTmp = m_iPicWidth>>1; 1759 } 1760 1761 memcpy(m_pTmpU1, pRec, sizeof(Pel)*picWidthTmp); 1762 1763 Int i; 1764 UInt edgeType; 1765 Pel* ppLumaTable = NULL; 1766 Pel* pClipTable = NULL; 1767 Int* pOffsetBo = NULL; 1768 Int typeIdx; 1769 1770 Int offset[LUMA_GROUP_NUM+1]; 1771 Int idxX; 1772 Int idxY; 1773 Int addr; 1774 Int frameWidthInCU = m_pcPic->getFrameWidthInCU(); 1775 Int frameHeightInCU = m_pcPic->getFrameHeightInCU(); 1776 Int stride; 1777 Pel *tmpUSwap; 1778 Int isChroma = (yCbCr == 0) ? 0:1; 1779 Bool mergeLeftFlag; 1780 Int saoBitIncrease = (yCbCr == 0) ? m_uiSaoBitIncreaseY : m_uiSaoBitIncreaseC; 1781 1782 pOffsetBo = (yCbCr==0) ? m_iOffsetBo : m_iChromaOffsetBo; 1783 1784 offset[0] = 0; 1785 for (idxY = 0; idxY< frameHeightInCU; idxY++) 1786 { 1787 addr = idxY * frameWidthInCU; 1788 if (yCbCr == 0) 1789 { 1790 pRec = m_pcPic->getPicYuvRec()->getLumaAddr(addr); 1791 stride = m_pcPic->getStride(); 1792 picWidthTmp = m_iPicWidth; 1793 } 1794 else if (yCbCr == 1) 1795 { 1796 pRec = m_pcPic->getPicYuvRec()->getCbAddr(addr); 1797 stride = m_pcPic->getCStride(); 1798 picWidthTmp = m_iPicWidth>>1; 1799 } 1800 else 1801 { 1802 pRec = m_pcPic->getPicYuvRec()->getCrAddr(addr); 1803 stride = m_pcPic->getCStride(); 1804 picWidthTmp = m_iPicWidth>>1; 1805 } 1806 1807 // pRec += iStride*(m_uiMaxCUHeight-1); 1808 for (i=0;i<(m_uiMaxCUHeight>>isChroma)+1;i++) 1809 { 1810 m_pTmpL1[i] = pRec[0]; 1811 pRec+=stride; 1812 } 1813 pRec-=(stride<<1); 1814 1815 memcpy(m_pTmpU2, pRec, sizeof(Pel)*picWidthTmp); 1816 1817 for (idxX = 0; idxX < frameWidthInCU; idxX++) 1818 { 1819 addr = idxY * frameWidthInCU + idxX; 1820 1821 if (oneUnitFlag) 1822 { 1823 typeIdx = saoLcuParam[0].typeIdx; 1824 mergeLeftFlag = (addr == 0)? 0:1; 1825 } 1826 else 1827 { 1828 typeIdx = saoLcuParam[addr].typeIdx; 1829 mergeLeftFlag = saoLcuParam[addr].mergeLeftFlag; 1830 } 1831 if (typeIdx>=0) 1832 { 1833 if (!mergeLeftFlag) 1834 { 1835 1836 if (typeIdx == SAO_BO) 1837 { 1838 for (i=0; i<SAO_MAX_BO_CLASSES+1;i++) 1839 { 1840 offset[i] = 0; 1841 } 1842 for (i=0; i<saoLcuParam[addr].length; i++) 1843 { 1844 offset[ (saoLcuParam[addr].subTypeIdx +i)%SAO_MAX_BO_CLASSES +1] = saoLcuParam[addr].offset[i] << saoBitIncrease; 1845 } 1846 1847 ppLumaTable = (yCbCr==0)?m_lumaTableBo:m_chromaTableBo; 1848 pClipTable = (yCbCr==0)?m_pClipTable:m_pChromaClipTable; 1849 1850 Int bitDepth = (yCbCr==0) ? g_bitDepthY : g_bitDepthC; 1851 for (i=0;i<(1<<bitDepth);i++) 1852 { 1853 pOffsetBo[i] = pClipTable[i + offset[ppLumaTable[i]]]; 1854 } 1855 1856 } 1857 if (typeIdx == SAO_EO_0 || typeIdx == SAO_EO_1 || typeIdx == SAO_EO_2 || typeIdx == SAO_EO_3) 1858 { 1859 for (i=0;i<saoLcuParam[addr].length;i++) 1860 { 1861 offset[i+1] = saoLcuParam[addr].offset[i] << saoBitIncrease; 1862 } 1863 for (edgeType=0;edgeType<6;edgeType++) 1864 { 1865 m_iOffsetEo[edgeType]= offset[m_auiEoTable[edgeType]]; 1866 } 1867 } 1868 } 1869 processSaoCu(addr, typeIdx, yCbCr); 1870 } 1871 else 1872 { 1873 if (idxX != (frameWidthInCU-1)) 1874 { 1875 if (yCbCr == 0) 1876 { 1877 pRec = m_pcPic->getPicYuvRec()->getLumaAddr(addr); 1878 stride = m_pcPic->getStride(); 1879 } 1880 else if (yCbCr == 1) 1881 { 1882 pRec = m_pcPic->getPicYuvRec()->getCbAddr(addr); 1883 stride = m_pcPic->getCStride(); 1884 } 1885 else 1886 { 1887 pRec = m_pcPic->getPicYuvRec()->getCrAddr(addr); 1888 stride = m_pcPic->getCStride(); 1889 } 1890 Int widthShift = m_uiMaxCUWidth>>isChroma; 1891 for (i=0;i<(m_uiMaxCUHeight>>isChroma)+1;i++) 1892 { 1893 m_pTmpL1[i] = pRec[widthShift-1]; 1894 pRec+=stride; 1895 } 1896 } 1897 } 1898 } 1899 tmpUSwap = m_pTmpU1; 1900 m_pTmpU1 = m_pTmpU2; 1901 m_pTmpU2 = tmpUSwap; 1902 } 1903 1904 } 1905 /** Reset SAO LCU part 1906 * \param saoLcuParam 1907 */ 1908 Void TComSampleAdaptiveOffset::resetLcuPart(SaoLcuParam* saoLcuParam) 1909 { 1910 Int i,j; 1911 for (i=0;i<m_iNumCuInWidth*m_iNumCuInHeight;i++) 1912 { 1913 saoLcuParam[i].mergeUpFlag = 1; 1914 saoLcuParam[i].mergeLeftFlag = 0; 1915 saoLcuParam[i].partIdx = 0; 1916 saoLcuParam[i].typeIdx = -1; 1917 for (j=0;j<MAX_NUM_SAO_OFFSETS;j++) 1918 { 1919 saoLcuParam[i].offset[j] = 0; 1920 } 1921 saoLcuParam[i].subTypeIdx = 0; 1922 } 1923 } 1924 1925 /** convert QP part to SAO unit 1926 * \param saoParam SAO parameter 1927 * \param partIdx SAO part index 1928 * \param yCbCr color component index 1929 */ 1930 Void TComSampleAdaptiveOffset::convertQT2SaoUnit(SAOParam *saoParam, UInt partIdx, Int yCbCr) 1931 { 1932 1933 SAOQTPart* saoPart= &(saoParam->psSaoPart[yCbCr][partIdx]); 1934 if (!saoPart->bSplit) 1935 { 1936 convertOnePart2SaoUnit(saoParam, partIdx, yCbCr); 1937 return; 1938 } 1939 1940 if (saoPart->PartLevel < m_uiMaxSplitLevel) 1941 { 1942 convertQT2SaoUnit(saoParam, saoPart->DownPartsIdx[0], yCbCr); 1943 convertQT2SaoUnit(saoParam, saoPart->DownPartsIdx[1], yCbCr); 1944 convertQT2SaoUnit(saoParam, saoPart->DownPartsIdx[2], yCbCr); 1945 convertQT2SaoUnit(saoParam, saoPart->DownPartsIdx[3], yCbCr); 1946 } 1947 } 1948 /** convert one SAO part to SAO unit 1949 * \param saoParam SAO parameter 1950 * \param partIdx SAO part index 1951 * \param yCbCr color component index 1952 */ 1953 Void TComSampleAdaptiveOffset::convertOnePart2SaoUnit(SAOParam *saoParam, UInt partIdx, Int yCbCr) 1954 { 1955 Int j; 1956 Int idxX; 1957 Int idxY; 1958 Int addr; 1959 Int frameWidthInCU = m_pcPic->getFrameWidthInCU(); 1960 SAOQTPart* saoQTPart = saoParam->psSaoPart[yCbCr]; 1961 SaoLcuParam* saoLcuParam = saoParam->saoLcuParam[yCbCr]; 1962 1963 for (idxY = saoQTPart[partIdx].StartCUY; idxY<= saoQTPart[partIdx].EndCUY; idxY++) 1964 { 1965 for (idxX = saoQTPart[partIdx].StartCUX; idxX<= saoQTPart[partIdx].EndCUX; idxX++) 1966 { 1967 addr = idxY * frameWidthInCU + idxX; 1968 saoLcuParam[addr].partIdxTmp = (Int)partIdx; 1969 saoLcuParam[addr].typeIdx = saoQTPart[partIdx].iBestType; 1970 saoLcuParam[addr].subTypeIdx = saoQTPart[partIdx].subTypeIdx; 1971 if (saoLcuParam[addr].typeIdx!=-1) 1972 { 1973 saoLcuParam[addr].length = saoQTPart[partIdx].iLength; 1974 for (j=0;j<MAX_NUM_SAO_OFFSETS;j++) 1975 { 1976 saoLcuParam[addr].offset[j] = saoQTPart[partIdx].iOffset[j]; 1977 } 1978 } 1979 else 1980 { 1981 saoLcuParam[addr].length = 0; 1982 saoLcuParam[addr].subTypeIdx = saoQTPart[partIdx].subTypeIdx; 1983 for (j=0;j<MAX_NUM_SAO_OFFSETS;j++) 1984 { 1985 saoLcuParam[addr].offset[j] = 0; 1986 } 1987 } 1988 } 1989 } 1990 } 1991 1992 Void TComSampleAdaptiveOffset::resetSaoUnit(SaoLcuParam* saoUnit) 1993 { 1994 saoUnit->partIdx = 0; 1995 saoUnit->partIdxTmp = 0; 1996 saoUnit->mergeLeftFlag = 0; 1997 saoUnit->mergeUpFlag = 0; 1998 saoUnit->typeIdx = -1; 1999 saoUnit->length = 0; 2000 saoUnit->subTypeIdx = 0; 2001 2002 for (Int i=0;i<4;i++) 2003 { 2004 saoUnit->offset[i] = 0; 2005 } 2006 } 2007 2008 Void TComSampleAdaptiveOffset::copySaoUnit(SaoLcuParam* saoUnitDst, SaoLcuParam* saoUnitSrc ) 2009 { 2010 saoUnitDst->mergeLeftFlag = saoUnitSrc->mergeLeftFlag; 2011 saoUnitDst->mergeUpFlag = saoUnitSrc->mergeUpFlag; 2012 saoUnitDst->typeIdx = saoUnitSrc->typeIdx; 2013 saoUnitDst->length = saoUnitSrc->length; 2014 2015 saoUnitDst->subTypeIdx = saoUnitSrc->subTypeIdx; 2016 for (Int i=0;i<4;i++) 2017 { 2018 saoUnitDst->offset[i] = saoUnitSrc->offset[i]; 2019 } 2020 } 2021 #endif 699 2022 700 /** PCM LF disable process. 2023 701 * \param pcPic picture (TComPic) pointer
Note: See TracChangeset for help on using the changeset viewer.