Changeset 459 in 3DVCSoftware for branches/HTM-DEV-0.3-dev1/source/Lib/TLibCommon/TComPrediction.cpp
- Timestamp:
- 6 Jun 2013, 11:46:05 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HTM-DEV-0.3-dev1/source/Lib/TLibCommon/TComPrediction.cpp
r446 r459 386 386 } 387 387 388 #if H_3D_DIM 389 Void TComPrediction::predIntraLumaDepth( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiIntraMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bFastEnc ) 390 { 391 assert( iWidth == iHeight ); 392 assert( iWidth >= DIM_MIN_SIZE && iWidth <= DIM_MAX_SIZE ); 393 assert( isDimMode( uiIntraMode ) ); 394 395 UInt dimType = getDimType ( uiIntraMode ); 396 Bool dimDeltaDC = isDimDeltaDC( uiIntraMode ); 397 Bool isDmmMode = (dimType < DMM_NUM_TYPE); 398 Bool isRbcMode = (dimType == RBC_IDX); 399 400 Bool* biSegPattern = NULL; 401 UInt patternStride = 0; 402 403 // get partiton 404 #if H_3D_DIM_DMM 405 TComWedgelet* dmmSegmentation = NULL; 406 if( isDmmMode ) 407 { 408 switch( dimType ) 409 { 410 case( DMM1_IDX ): 411 { 412 dmmSegmentation = &(g_dmmWedgeLists[ g_aucConvertToBit[iWidth] ][ pcCU->getDmmWedgeTabIdx( dimType, uiAbsPartIdx ) ]); 413 } break; 414 case( DMM2_IDX ): 415 { 416 UInt uiTabIdx = 0; 417 if( bFastEnc ) { uiTabIdx = pcCU->getDmmWedgeTabIdx( dimType, uiAbsPartIdx ); } 418 else 419 { 420 uiTabIdx = xPredWedgeFromIntra( pcCU, uiAbsPartIdx, iWidth, iHeight, pcCU->getDmm2DeltaEnd( uiAbsPartIdx ) ); 421 pcCU->setDmmWedgeTabIdxSubParts( uiTabIdx, dimType, uiAbsPartIdx, (pcCU->getDepth(0) + (pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1)) ); 422 } 423 dmmSegmentation = &(g_dmmWedgeLists[ g_aucConvertToBit[iWidth] ][ uiTabIdx ]); 424 } break; 425 case( DMM3_IDX ): 426 { 427 UInt uiTabIdx = 0; 428 if( bFastEnc ) { uiTabIdx = pcCU->getDmmWedgeTabIdx( dimType, uiAbsPartIdx ); } 429 else 430 { 431 uiTabIdx = xPredWedgeFromTex( pcCU, uiAbsPartIdx, iWidth, iHeight, pcCU->getDmm3IntraTabIdx( uiAbsPartIdx ) ); 432 pcCU->setDmmWedgeTabIdxSubParts( uiTabIdx, dimType, uiAbsPartIdx, (pcCU->getDepth(0) + (pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1)) ); 433 } 434 dmmSegmentation = &(g_dmmWedgeLists[ g_aucConvertToBit[iWidth] ][ uiTabIdx ]); 435 } break; 436 case( DMM4_IDX ): 437 { 438 dmmSegmentation = new TComWedgelet( iWidth, iHeight ); 439 xPredContourFromTex( pcCU, uiAbsPartIdx, iWidth, iHeight, dmmSegmentation ); 440 } break; 441 default: assert(0); 442 } 443 assert( dmmSegmentation ); 444 biSegPattern = dmmSegmentation->getPattern(); 445 patternStride = dmmSegmentation->getStride (); 446 } 447 #endif 448 #if H_3D_DIM_RBC 449 if( isRbcMode ) 450 { 451 biSegPattern = pcCU->getEdgePartition( uiAbsPartIdx ); 452 patternStride = iWidth; 453 } 454 #endif 455 456 // get predicted partition values 457 assert( biSegPattern ); 458 Int* piMask = NULL; 459 if( isDmmMode ) piMask = pcCU->getPattern()->getAdiOrgBuf( iWidth, iHeight, m_piYuvExt ); // no filtering for DMM 460 else piMask = pcCU->getPattern()->getPredictorPtr( 0, g_aucConvertToBit[ iWidth ] + 2, m_piYuvExt ); 461 assert( piMask ); 462 Int maskStride = 2*iWidth + 1; 463 Int* ptrSrc = piMask+maskStride+1; 464 Pel predDC1 = 0; Pel predDC2 = 0; 465 xPredBiSegDCs( ptrSrc, maskStride, biSegPattern, patternStride, predDC1, predDC2 ); 466 467 // set segment values with deltaDC offsets 468 Pel segDC1 = 0; 469 Pel segDC2 = 0; 470 if( dimDeltaDC ) 471 { 472 Pel deltaDC1 = pcCU->getDimDeltaDC( dimType, 0, uiAbsPartIdx ); 473 Pel deltaDC2 = pcCU->getDimDeltaDC( dimType, 1, uiAbsPartIdx ); 474 #if H_3D_DIM_DMM 475 if( isDmmMode ) 476 { 477 #if H_3D_DIM_DLT 478 segDC1 = GetIdx2DepthValue( GetDepthValue2Idx( predDC1 ) + deltaDC1 ); 479 segDC2 = GetIdx2DepthValue( GetDepthValue2Idx( predDC2 ) + deltaDC2 ); 480 #else 481 segDC1 = ClipY( predDC1 + deltaDC1 ); 482 segDC2 = ClipY( predDC2 + deltaDC2 ); 483 #endif 484 } 485 #endif 486 #if H_3D_DIM_RBC 487 if( isRbcMode ) 488 { 489 xDeltaDCQuantScaleUp( pcCU, deltaDC1 ); 490 xDeltaDCQuantScaleUp( pcCU, deltaDC2 ); 491 segDC1 = ClipY( predDC1 + deltaDC1 ); 492 segDC2 = ClipY( predDC2 + deltaDC2 ); 493 } 494 #endif 495 } 496 else 497 { 498 segDC1 = predDC1; 499 segDC2 = predDC2; 500 } 501 502 // set prediction signal 503 Pel* pDst = piPred; 504 xAssignBiSegDCs( pDst, uiStride, biSegPattern, patternStride, segDC1, segDC2 ); 505 506 #if H_3D_DIM_DMM 507 if( dimType == DMM4_IDX ) { dmmSegmentation->destroy(); delete dmmSegmentation; } 508 #endif 509 } 510 #endif 511 388 512 /** Function for checking identical motion. 389 513 * \param TComDataCU* pcCU … … 758 882 return; 759 883 } 884 885 #if H_3D_DIM 886 Void TComPrediction::xPredBiSegDCs( Int* ptrSrc, UInt srcStride, Bool* biSegPattern, Int patternStride, Pel& predDC1, Pel& predDC2 ) 887 { 888 Int refDC1, refDC2; 889 const Int iTR = ( patternStride - 1 ) - srcStride; 890 const Int iTM = ( ( patternStride - 1 ) >> 1 ) - srcStride; 891 const Int iLB = ( patternStride - 1 ) * srcStride - 1; 892 const Int iLM = ( ( patternStride - 1 ) >> 1 ) * srcStride - 1; 893 894 Bool bL = ( biSegPattern[0] != biSegPattern[(patternStride-1)*patternStride] ); 895 Bool bT = ( biSegPattern[0] != biSegPattern[(patternStride-1)] ); 896 897 if( bL == bT ) 898 { 899 refDC1 = bL ? ( ptrSrc[iTR] + ptrSrc[iLB] )>>1 : 1<<( g_bitDepthY - 1 ); 900 refDC2 = ( ptrSrc[ -1] + ptrSrc[-(Int)srcStride] )>>1; 901 } 902 else 903 { 904 refDC1 = bL ? ptrSrc[iLB] : ptrSrc[iTR]; 905 refDC2 = bL ? ptrSrc[iTM] : ptrSrc[iLM]; 906 } 907 908 predDC1 = biSegPattern[0] ? refDC1 : refDC2; 909 predDC2 = biSegPattern[0] ? refDC2 : refDC1; 910 } 911 912 Void TComPrediction::xAssignBiSegDCs( Pel* ptrDst, UInt dstStride, Bool* biSegPattern, Int patternStride, Pel valDC1, Pel valDC2 ) 913 { 914 if( dstStride == patternStride ) 915 { 916 for( UInt k = 0; k < (patternStride * patternStride); k++ ) 917 { 918 if( true == biSegPattern[k] ) { ptrDst[k] = valDC2; } 919 else { ptrDst[k] = valDC1; } 920 } 921 } 922 else 923 { 924 Pel* piTemp = ptrDst; 925 for( UInt uiY = 0; uiY < patternStride; uiY++ ) 926 { 927 for( UInt uiX = 0; uiX < patternStride; uiX++ ) 928 { 929 if( true == biSegPattern[uiX] ) { piTemp[uiX] = valDC2; } 930 else { piTemp[uiX] = valDC1; } 931 } 932 piTemp += dstStride; 933 biSegPattern += patternStride; 934 } 935 } 936 } 937 938 #if H_3D_DIM_DMM 939 UInt TComPrediction::xPredWedgeFromIntra( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, Int iDeltaEnd ) 940 { 941 UInt uiThisBlockSize = uiWidth; 942 943 TComDataCU* pcTempCU; 944 UInt uiTempPartIdx; 945 // 1st: try continue above wedgelet 946 pcTempCU = pcCU->getPUAbove( uiTempPartIdx, pcCU->getZorderIdxInCU() + uiAbsPartIdx ); 947 if( pcTempCU && isDimMode( pcTempCU->getLumaIntraDir( uiTempPartIdx ) ) ) 948 { 949 UInt dimType = getDimType( pcTempCU->getLumaIntraDir( uiTempPartIdx ) ); 950 if( DMM1_IDX == dimType || DMM2_IDX == dimType || DMM3_IDX == dimType ) 951 { 952 // get offset between current and reference block 953 UInt uiOffsetX = 0, uiOffsetY = 0; 954 xGetBlockOffset( pcCU, uiAbsPartIdx, pcTempCU, uiTempPartIdx, uiOffsetX, uiOffsetY ); 955 956 // get reference wedgelet 957 WedgeList* pacWedgeList = &g_dmmWedgeLists[(g_aucConvertToBit[(pcTempCU->getWidth( uiTempPartIdx )>>((pcTempCU->getPartitionSize( uiTempPartIdx ) == SIZE_NxN) ? 1 : 0))])]; 958 TComWedgelet* pcRefWedgelet = &(pacWedgeList->at( pcTempCU->getDmmWedgeTabIdx( dimType, uiTempPartIdx ) ) ); 959 960 // find wedgelet, if direction is suitable for continue wedge 961 if( pcRefWedgelet->checkPredDirAbovePossible( uiThisBlockSize, uiOffsetX ) ) 962 { 963 UChar uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye; 964 pcRefWedgelet->getPredDirStartEndAbove( uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye, uiThisBlockSize, uiOffsetX, iDeltaEnd ); 965 return xGetWedgePatternIdx( uiThisBlockSize, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye ); 966 } 967 } 968 } 969 970 // 2nd: try continue left wedglelet 971 pcTempCU = pcCU->getPULeft( uiTempPartIdx, pcCU->getZorderIdxInCU() + uiAbsPartIdx ); 972 if( pcTempCU && isDimMode( pcTempCU->getLumaIntraDir( uiTempPartIdx ) ) ) 973 { 974 UInt dimType = getDimType( pcTempCU->getLumaIntraDir( uiTempPartIdx ) ); 975 if( DMM1_IDX == dimType || DMM2_IDX == dimType || DMM3_IDX == dimType ) 976 { 977 // get offset between current and reference block 978 UInt uiOffsetX = 0, uiOffsetY = 0; 979 xGetBlockOffset( pcCU, uiAbsPartIdx, pcTempCU, uiTempPartIdx, uiOffsetX, uiOffsetY ); 980 981 // get reference wedgelet 982 WedgeList* pacWedgeList = &g_dmmWedgeLists[(g_aucConvertToBit[(pcTempCU->getWidth( uiTempPartIdx )>>((pcTempCU->getPartitionSize( uiTempPartIdx ) == SIZE_NxN) ? 1 : 0))])]; 983 TComWedgelet* pcRefWedgelet = &(pacWedgeList->at( pcTempCU->getDmmWedgeTabIdx( dimType, uiTempPartIdx ) ) ); 984 985 // find wedgelet, if direction is suitable for continue wedge 986 if( pcRefWedgelet->checkPredDirLeftPossible( uiThisBlockSize, uiOffsetY ) ) 987 { 988 UChar uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye; 989 pcRefWedgelet->getPredDirStartEndLeft( uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye, uiThisBlockSize, uiOffsetY, iDeltaEnd ); 990 return xGetWedgePatternIdx( uiThisBlockSize, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye ); 991 } 992 } 993 } 994 995 // 3rd: (default) make wedglet from intra dir and max slope point 996 Int iSlopeX = 0, iSlopeY = 0; 997 UInt uiStartPosX = 0, uiStartPosY = 0; 998 if( xGetWedgeIntraDirPredData( pcCU, uiAbsPartIdx, uiThisBlockSize, iSlopeX, iSlopeY, uiStartPosX, uiStartPosY ) ) 999 { 1000 UChar uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye; 1001 xGetWedgeIntraDirStartEnd( pcCU, uiAbsPartIdx, uiThisBlockSize, iSlopeX, iSlopeY, uiStartPosX, uiStartPosY, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye, iDeltaEnd ); 1002 return xGetWedgePatternIdx( uiThisBlockSize, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye ); 1003 } 1004 1005 return 0; 1006 } 1007 1008 UInt TComPrediction::xPredWedgeFromTex( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt intraTabIdx ) 1009 { 1010 TComPic* pcPicTex = pcCU->getSlice()->getPicLists()->getPic( pcCU->getSlice()->getViewIndex(), false, pcCU->getSlice()->getPOC() ); 1011 assert( pcPicTex != NULL ); 1012 TComDataCU* pcColTexCU = pcPicTex->getCU(pcCU->getAddr()); 1013 UInt uiTexPartIdx = pcCU->getZorderIdxInCU() + uiAbsPartIdx; 1014 Int uiColTexIntraDir = pcColTexCU->isIntra( uiTexPartIdx ) ? pcColTexCU->getLumaIntraDir( uiTexPartIdx ) : 255; 1015 1016 if( uiColTexIntraDir > DC_IDX && uiColTexIntraDir < 35 ) { return g_aauiWdgLstM3[g_aucConvertToBit[uiWidth]][uiColTexIntraDir-2].at(intraTabIdx); } 1017 else { return g_dmmWedgeNodeLists[(g_aucConvertToBit[uiWidth])].at(intraTabIdx).getPatternIdx(); } 1018 } 1019 1020 Void TComPrediction::xPredContourFromTex( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, TComWedgelet* pcContourWedge ) 1021 { 1022 pcContourWedge->clear(); 1023 1024 // get copy of co-located texture luma block 1025 TComYuv cTempYuv; 1026 cTempYuv.create( uiWidth, uiHeight ); 1027 cTempYuv.clear(); 1028 Pel* piRefBlkY = cTempYuv.getLumaAddr(); 1029 xCopyTextureLumaBlock( pcCU, uiAbsPartIdx, piRefBlkY, uiWidth, uiHeight ); 1030 piRefBlkY = cTempYuv.getLumaAddr(); 1031 1032 // find contour for texture luma block 1033 UInt iDC = 0; 1034 for( UInt k = 0; k < (uiWidth*uiHeight); k++ ) 1035 { 1036 iDC += piRefBlkY[k]; 1037 } 1038 iDC /= (uiWidth*uiHeight); 1039 piRefBlkY = cTempYuv.getLumaAddr(); 1040 1041 Bool* pabContourPattern = pcContourWedge->getPattern(); 1042 for( UInt k = 0; k < (uiWidth*uiHeight); k++ ) 1043 { 1044 pabContourPattern[k] = (piRefBlkY[k] > iDC) ? true : false; 1045 } 1046 1047 cTempYuv.destroy(); 1048 } 1049 1050 1051 Void TComPrediction::xCopyTextureLumaBlock( TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* piDestBlockY, UInt uiWidth, UInt uiHeight ) 1052 { 1053 TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getPicLists()->getPic( pcCU->getSlice()->getViewIndex(), false, pcCU->getSlice()->getPOC() )->getPicYuvRec(); 1054 assert( pcPicYuvRef != NULL ); 1055 Int iRefStride = pcPicYuvRef->getStride(); 1056 Pel* piRefY = pcPicYuvRef->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiAbsPartIdx ); 1057 1058 for ( Int y = 0; y < uiHeight; y++ ) 1059 { 1060 ::memcpy(piDestBlockY, piRefY, sizeof(Pel)*uiWidth); 1061 piDestBlockY += uiWidth; 1062 piRefY += iRefStride; 1063 } 1064 } 1065 1066 Void TComPrediction::xGetBlockOffset( TComDataCU* pcCU, UInt uiAbsPartIdx, TComDataCU* pcRefCU, UInt uiRefAbsPartIdx, UInt& ruiOffsetX, UInt& ruiOffsetY ) 1067 { 1068 ruiOffsetX = 0; 1069 ruiOffsetY = 0; 1070 1071 // get offset between current and above/left block 1072 UInt uiThisOriginX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ]; 1073 UInt uiThisOriginY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ]; 1074 1075 UInt uiNumPartInRefCU = pcRefCU->getTotalNumPart(); 1076 UInt uiMaxDepthRefCU = 0; 1077 while( uiNumPartInRefCU > 1 ) 1078 { 1079 uiNumPartInRefCU >>= 2; 1080 uiMaxDepthRefCU++; 1081 } 1082 1083 UInt uiDepthRefPU = (pcRefCU->getDepth(uiRefAbsPartIdx)) + (pcRefCU->getPartitionSize(uiRefAbsPartIdx) == SIZE_2Nx2N ? 0 : 1); 1084 UInt uiShifts = (uiMaxDepthRefCU - uiDepthRefPU)*2; 1085 UInt uiRefBlockOriginPartIdx = (uiRefAbsPartIdx>>uiShifts)<<uiShifts; 1086 1087 UInt uiRefOriginX = pcRefCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiRefBlockOriginPartIdx] ]; 1088 UInt uiRefOriginY = pcRefCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiRefBlockOriginPartIdx] ]; 1089 1090 if( (uiThisOriginX - uiRefOriginX) > 0 ) { ruiOffsetX = (UInt)(uiThisOriginX - uiRefOriginX); } 1091 if( (uiThisOriginY - uiRefOriginY) > 0 ) { ruiOffsetY = (UInt)(uiThisOriginY - uiRefOriginY); } 1092 } 1093 1094 Bool TComPrediction::xGetWedgeIntraDirPredData( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiBlockSize, Int& riSlopeX, Int& riSlopeY, UInt& ruiStartPosX, UInt& ruiStartPosY ) 1095 { 1096 riSlopeX = 0, riSlopeY = 0, ruiStartPosX = 0, ruiStartPosY = 0; 1097 1098 // 1st step: get wedge start point (max. slope) 1099 Int* piSource = pcCU->getPattern()->getAdiOrgBuf( uiBlockSize, uiBlockSize, m_piYuvExt ); 1100 Int iSourceStride = ( uiBlockSize<<1 ) + 1; 1101 1102 UInt uiSlopeMaxAbove = 0, uiPosSlopeMaxAbove = 0; 1103 for( UInt uiPosHor = 0; uiPosHor < (uiBlockSize-1); uiPosHor++ ) 1104 { 1105 if( abs( piSource[uiPosHor+1] - piSource[uiPosHor] ) > uiSlopeMaxAbove ) 1106 { 1107 uiSlopeMaxAbove = abs( piSource[uiPosHor+1] - piSource[uiPosHor] ); 1108 uiPosSlopeMaxAbove = uiPosHor; 1109 } 1110 } 1111 1112 UInt uiSlopeMaxLeft = 0, uiPosSlopeMaxLeft = 0; 1113 for( UInt uiPosVer = 0; uiPosVer < (uiBlockSize-1); uiPosVer++ ) 1114 { 1115 if( abs( piSource[(uiPosVer+1)*iSourceStride] - piSource[uiPosVer*iSourceStride] ) > uiSlopeMaxLeft ) 1116 { 1117 uiSlopeMaxLeft = abs( piSource[(uiPosVer+1)*iSourceStride] - piSource[uiPosVer*iSourceStride] ); 1118 uiPosSlopeMaxLeft = uiPosVer; 1119 } 1120 } 1121 1122 if( uiSlopeMaxAbove == 0 && uiSlopeMaxLeft == 0 ) 1123 { 1124 return false; 1125 } 1126 1127 ruiStartPosX = ( uiSlopeMaxAbove > uiSlopeMaxLeft ) ? uiPosSlopeMaxAbove : 0; 1128 ruiStartPosY = ( uiSlopeMaxLeft >= uiSlopeMaxAbove ) ? uiPosSlopeMaxLeft : 0; 1129 1130 // 2nd step: derive wedge direction 1131 Int uiPreds[3] = {-1, -1, -1}; 1132 Int iMode = -1; 1133 Int iPredNum = pcCU->getIntraDirLumaPredictor( uiAbsPartIdx, uiPreds, &iMode ); 1134 1135 UInt uiDirMode = 0; 1136 if( iMode >= 0 ) { iPredNum = iMode; } 1137 if( iPredNum == 1 ) { uiDirMode = uiPreds[0]; } 1138 if( iPredNum == 2 ) { uiDirMode = uiPreds[1]; } 1139 1140 if( uiDirMode < 2 ) { return false; } // no planar & DC 1141 1142 Bool modeHor = (uiDirMode < 18); 1143 Bool modeVer = !modeHor; 1144 Int intraPredAngle = modeVer ? (Int)uiDirMode - VER_IDX : modeHor ? -((Int)uiDirMode - HOR_IDX) : 0; 1145 Int absAng = abs(intraPredAngle); 1146 Int signAng = intraPredAngle < 0 ? -1 : 1; 1147 Int angTable[9] = {0,2,5,9,13,17,21,26,32}; 1148 absAng = angTable[absAng]; 1149 intraPredAngle = signAng * absAng; 1150 1151 // 3rd step: set slope for direction 1152 if( modeHor ) 1153 { 1154 riSlopeX = ( intraPredAngle > 0 ) ? -32 : 32; 1155 riSlopeY = ( intraPredAngle > 0 ) ? intraPredAngle : -intraPredAngle; 1156 } 1157 else if( modeVer ) 1158 { 1159 riSlopeX = ( intraPredAngle > 0 ) ? intraPredAngle : -intraPredAngle; 1160 riSlopeY = ( intraPredAngle > 0 ) ? -32 : 32; 1161 } 1162 1163 return true; 1164 } 1165 1166 Void TComPrediction::xGetWedgeIntraDirStartEnd( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiBlockSize, Int iDeltaX, Int iDeltaY, UInt uiPMSPosX, UInt uiPMSPosY, UChar& ruhXs, UChar& ruhYs, UChar& ruhXe, UChar& ruhYe, Int iDeltaEnd ) 1167 { 1168 ruhXs = 0; 1169 ruhYs = 0; 1170 ruhXe = 0; 1171 ruhYe = 0; 1172 1173 // scaling of start pos and block size to wedge resolution 1174 UInt uiScaledStartPosX = 0; 1175 UInt uiScaledStartPosY = 0; 1176 UInt uiScaledBlockSize = 0; 1177 WedgeResolution eWedgeRes = g_dmmWedgeResolution[(UInt)g_aucConvertToBit[uiBlockSize]]; 1178 switch( eWedgeRes ) 1179 { 1180 case( DOUBLE_PEL ): { uiScaledStartPosX = (uiPMSPosX>>1); uiScaledStartPosY = (uiPMSPosY>>1); uiScaledBlockSize = (uiBlockSize>>1); break; } 1181 case( FULL_PEL ): { uiScaledStartPosX = uiPMSPosX; uiScaledStartPosY = uiPMSPosY; uiScaledBlockSize = uiBlockSize; break; } 1182 case( HALF_PEL ): { uiScaledStartPosX = (uiPMSPosX<<1); uiScaledStartPosY = (uiPMSPosY<<1); uiScaledBlockSize = (uiBlockSize<<1); break; } 1183 } 1184 Int iMaxPos = (Int)uiScaledBlockSize - 1; 1185 1186 // case above 1187 if( uiScaledStartPosX > 0 && uiScaledStartPosY == 0 ) 1188 { 1189 ruhXs = (UChar)uiScaledStartPosX; 1190 ruhYs = 0; 1191 1192 if( iDeltaY == 0 ) 1193 { 1194 if( iDeltaX < 0 ) 1195 { 1196 ruhXe = 0; 1197 ruhYe = (UChar)std::min( std::max( iDeltaEnd, 0 ), iMaxPos ); 1198 return; 1199 } 1200 else 1201 { 1202 ruhXe = (UChar)iMaxPos; 1203 ruhYe = (UChar)std::min( std::max( -iDeltaEnd, 0 ), iMaxPos ); 1204 std::swap( ruhXs, ruhXe ); 1205 std::swap( ruhYs, ruhYe ); 1206 return; 1207 } 1208 } 1209 1210 // regular case 1211 Int iVirtualEndX = (Int)ruhXs + roftoi( (Double)iMaxPos * ((Double)iDeltaX / (Double)iDeltaY) ); 1212 1213 if( iVirtualEndX < 0 ) 1214 { 1215 Int iYe = roftoi( (Double)(0 - (Int)ruhXs) * ((Double)iDeltaY / (Double)iDeltaX) ) + iDeltaEnd; 1216 if( iYe < (Int)uiScaledBlockSize ) 1217 { 1218 ruhXe = 0; 1219 ruhYe = (UChar)std::max( iYe, 0 ); 1220 return; 1221 } 1222 else 1223 { 1224 ruhXe = (UChar)std::min( (iYe - iMaxPos), iMaxPos ); 1225 ruhYe = (UChar)iMaxPos; 1226 return; 1227 } 1228 } 1229 else if( iVirtualEndX > iMaxPos ) 1230 { 1231 Int iYe = roftoi( (Double)(iMaxPos - (Int)ruhXs) * ((Double)iDeltaY / (Double)iDeltaX) ) - iDeltaEnd; 1232 if( iYe < (Int)uiScaledBlockSize ) 1233 { 1234 ruhXe = (UChar)iMaxPos; 1235 ruhYe = (UChar)std::max( iYe, 0 ); 1236 std::swap( ruhXs, ruhXe ); 1237 std::swap( ruhYs, ruhYe ); 1238 return; 1239 } 1240 else 1241 { 1242 ruhXe = (UChar)std::max( (iMaxPos - (iYe - iMaxPos)), 0 ); 1243 ruhYe = (UChar)iMaxPos; 1244 return; 1245 } 1246 } 1247 else 1248 { 1249 Int iXe = iVirtualEndX + iDeltaEnd; 1250 if( iXe < 0 ) 1251 { 1252 ruhXe = 0; 1253 ruhYe = (UChar)std::max( (iMaxPos + iXe), 0 ); 1254 return; 1255 } 1256 else if( iXe > iMaxPos ) 1257 { 1258 ruhXe = (UChar)iMaxPos; 1259 ruhYe = (UChar)std::max( (iMaxPos - (iXe - iMaxPos)), 0 ); 1260 std::swap( ruhXs, ruhXe ); 1261 std::swap( ruhYs, ruhYe ); 1262 return; 1263 } 1264 else 1265 { 1266 ruhXe = (UChar)iXe; 1267 ruhYe = (UChar)iMaxPos; 1268 return; 1269 } 1270 } 1271 } 1272 1273 // case left 1274 if( uiScaledStartPosY > 0 && uiScaledStartPosX == 0 ) 1275 { 1276 ruhXs = 0; 1277 ruhYs = (UChar)uiScaledStartPosY; 1278 1279 if( iDeltaX == 0 ) 1280 { 1281 if( iDeltaY < 0 ) 1282 { 1283 ruhXe = (UChar)std::min( std::max( -iDeltaEnd, 0 ), iMaxPos ); 1284 ruhYe = 0; 1285 std::swap( ruhXs, ruhXe ); 1286 std::swap( ruhYs, ruhYe ); 1287 return; 1288 } 1289 else 1290 { 1291 ruhXe = (UChar)std::min( std::max( iDeltaEnd, 0 ), iMaxPos ); 1292 ruhYe = (UChar)iMaxPos; 1293 return; 1294 } 1295 } 1296 1297 // regular case 1298 Int iVirtualEndY = (Int)ruhYs + roftoi( (Double)iMaxPos * ((Double)iDeltaY / (Double)iDeltaX) ); 1299 1300 if( iVirtualEndY < 0 ) 1301 { 1302 Int iXe = roftoi( (Double)(0 - (Int)ruhYs ) * ((Double)iDeltaX / (Double)iDeltaY) ) - iDeltaEnd; 1303 if( iXe < (Int)uiScaledBlockSize ) 1304 { 1305 ruhXe = (UChar)std::max( iXe, 0 ); 1306 ruhYe = 0; 1307 std::swap( ruhXs, ruhXe ); 1308 std::swap( ruhYs, ruhYe ); 1309 return; 1310 } 1311 else 1312 { 1313 ruhXe = (UChar)iMaxPos; 1314 ruhYe = (UChar)std::min( (iXe - iMaxPos), iMaxPos ); 1315 std::swap( ruhXs, ruhXe ); 1316 std::swap( ruhYs, ruhYe ); 1317 return; 1318 } 1319 } 1320 else if( iVirtualEndY > (uiScaledBlockSize-1) ) 1321 { 1322 Int iXe = roftoi( (Double)((Int)(uiScaledBlockSize-1) - (Int)ruhYs ) * ((Double)iDeltaX / (Double)iDeltaY) ) + iDeltaEnd; 1323 if( iXe < (Int)uiScaledBlockSize ) 1324 { 1325 ruhXe = (UChar)std::max( iXe, 0 ); 1326 ruhYe = (UChar)(uiScaledBlockSize-1); 1327 return; 1328 } 1329 else 1330 { 1331 ruhXe = (UChar)iMaxPos; 1332 ruhYe = (UChar)std::max( (iMaxPos - (iXe - iMaxPos)), 0 ); 1333 std::swap( ruhXs, ruhXe ); 1334 std::swap( ruhYs, ruhYe ); 1335 return; 1336 } 1337 } 1338 else 1339 { 1340 Int iYe = iVirtualEndY - iDeltaEnd; 1341 if( iYe < 0 ) 1342 { 1343 ruhXe = (UChar)std::max( (iMaxPos + iYe), 0 ); 1344 ruhYe = 0; 1345 std::swap( ruhXs, ruhXe ); 1346 std::swap( ruhYs, ruhYe ); 1347 return; 1348 } 1349 else if( iYe > iMaxPos ) 1350 { 1351 ruhXe = (UChar)std::max( (iMaxPos - (iYe - iMaxPos)), 0 ); 1352 ruhYe = (UChar)iMaxPos; 1353 return; 1354 } 1355 else 1356 { 1357 ruhXe = (UChar)iMaxPos; 1358 ruhYe = (UChar)iYe; 1359 std::swap( ruhXs, ruhXe ); 1360 std::swap( ruhYs, ruhYe ); 1361 return; 1362 } 1363 } 1364 } 1365 1366 // case origin 1367 if( uiScaledStartPosX == 0 && uiScaledStartPosY == 0 ) 1368 { 1369 if( iDeltaX*iDeltaY < 0 ) 1370 { 1371 return; 1372 } 1373 1374 ruhXs = 0; 1375 ruhYs = 0; 1376 1377 if( iDeltaY == 0 ) 1378 { 1379 ruhXe = (UChar)iMaxPos; 1380 ruhYe = 0; 1381 std::swap( ruhXs, ruhXe ); 1382 std::swap( ruhYs, ruhYe ); 1383 return; 1384 } 1385 1386 if( iDeltaX == 0 ) 1387 { 1388 ruhXe = 0; 1389 ruhYe = (UChar)iMaxPos; 1390 return; 1391 } 1392 1393 Int iVirtualEndX = (Int)ruhXs + roftoi( (Double)iMaxPos * ((Double)iDeltaX / (Double)iDeltaY) ); 1394 1395 if( iVirtualEndX > iMaxPos ) 1396 { 1397 Int iYe = roftoi( (Double)((Int)iMaxPos - (Int)ruhXs) * ((Double)iDeltaY / (Double)iDeltaX) ) - iDeltaEnd; 1398 if( iYe < (Int)uiScaledBlockSize ) 1399 { 1400 ruhXe = (UChar)(uiScaledBlockSize-1); 1401 ruhYe = (UChar)std::max( iYe, 0 ); 1402 std::swap( ruhXs, ruhXe ); 1403 std::swap( ruhYs, ruhYe ); 1404 return; 1405 } 1406 else 1407 { 1408 ruhXe = (UChar)std::max( (iMaxPos - (iYe - iMaxPos)), 0 ); 1409 ruhYe = (UChar)(uiScaledBlockSize-1); 1410 return; 1411 } 1412 } 1413 else 1414 { 1415 Int iXe = iVirtualEndX + iDeltaEnd; 1416 if( iXe < 0 ) 1417 { 1418 ruhXe = 0; 1419 ruhYe = (UChar)std::max( (iMaxPos + iXe), 0 ); 1420 return; 1421 } 1422 else if( iXe > iMaxPos ) 1423 { 1424 ruhXe = (UChar)(uiScaledBlockSize-1); 1425 ruhYe = (UChar)std::max( (iMaxPos - (iXe - iMaxPos)), 0 ); 1426 std::swap( ruhXs, ruhXe ); 1427 std::swap( ruhYs, ruhYe ); 1428 return; 1429 } 1430 else 1431 { 1432 ruhXe = (UChar)iXe; 1433 ruhYe = (UChar)(uiScaledBlockSize-1); 1434 return; 1435 } 1436 } 1437 } 1438 } 1439 1440 UInt TComPrediction::xGetWedgePatternIdx( UInt uiBlockSize, UChar uhXs, UChar uhYs, UChar uhXe, UChar uhYe ) 1441 { 1442 WedgeRefList* pcWedgeRefList = &g_dmmWedgeRefLists[(g_aucConvertToBit[uiBlockSize])]; 1443 for( UInt uiIdx = 0; uiIdx < pcWedgeRefList->size(); uiIdx++ ) 1444 { 1445 TComWedgeRef* pcTestWedgeRef = &(pcWedgeRefList->at(uiIdx)); 1446 if( pcTestWedgeRef->getStartX() == uhXs && pcTestWedgeRef->getStartY() == uhYs && pcTestWedgeRef->getEndX() == uhXe && pcTestWedgeRef->getEndY() == uhYe ) 1447 { 1448 return pcTestWedgeRef->getRefIdx(); 1449 } 1450 } 1451 return 0; 1452 } 1453 #endif 1454 #if H_3D_DIM_RBC 1455 Void TComPrediction::xDeltaDCQuantScaleUp( TComDataCU* pcCU, Pel& rDeltaDC ) 1456 { 1457 Int iSign = rDeltaDC < 0 ? -1 : 1; 1458 UInt uiAbs = abs( rDeltaDC ); 1459 1460 Int iQp = pcCU->getQP(0); 1461 Double dMax = (Double)( 1<<( g_bitDepthY - 1 ) ); 1462 Double dStepSize = Clip3( 1.0, dMax, pow( 2.0, iQp/10.0 - 2.0 ) ); 1463 1464 rDeltaDC = iSign * roftoi( uiAbs * dStepSize ); 1465 return; 1466 } 1467 1468 Void TComPrediction::xDeltaDCQuantScaleDown( TComDataCU* pcCU, Pel& rDeltaDC ) 1469 { 1470 Int iSign = rDeltaDC < 0 ? -1 : 1; 1471 UInt uiAbs = abs( rDeltaDC ); 1472 1473 Int iQp = pcCU->getQP(0); 1474 Double dMax = (Double)( 1<<( g_bitDepthY - 1 ) ); 1475 Double dStepSize = Clip3( 1.0, dMax, pow( 2.0, iQp/10.0 - 2.0 ) ); 1476 1477 rDeltaDC = iSign * roftoi( uiAbs / dStepSize ); 1478 return; 1479 } 1480 #endif 1481 #endif 760 1482 //! \}
Note: See TracChangeset for help on using the changeset viewer.