Changeset 1313 in 3DVCSoftware for trunk/source/Lib/TLibEncoder/TEncSlice.cpp
- Timestamp:
- 13 Aug 2015, 17:38:13 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/Lib/TLibEncoder/TEncSlice.cpp
r1196 r1313 2 2 * License, included below. This software may be subject to other third party 3 3 * and contributor rights, including patent rights, and no such rights are 4 * granted under this license. 4 * granted under this license. 5 5 * 6 * Copyright (c) 2010-2015, ITU/ISO/IEC6 * Copyright (c) 2010-2015, ITU/ISO/IEC 7 7 * All rights reserved. 8 8 * … … 46 46 // Constructor / destructor / create / destroy 47 47 // ==================================================================================================================== 48 49 48 TEncSlice::TEncSlice() 49 : m_encCABACTableIdx(I_SLICE) 50 50 { 51 51 m_apcPicYuvPred = NULL; 52 52 m_apcPicYuvResi = NULL; 53 53 54 54 m_pdRdPicLambda = NULL; 55 55 m_pdRdPicQp = NULL; 56 56 m_piRdPicQp = NULL; 57 m_pcBufferSbacCoders = NULL;58 m_pcBufferBinCoderCABACs = NULL;59 m_pcBufferLowLatSbacCoders = NULL;60 m_pcBufferLowLatBinCoderCABACs = NULL;61 57 } 62 58 63 59 TEncSlice::~TEncSlice() 64 60 { 65 for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++) 66 { 67 delete (*i); 68 } 69 } 70 71 Void TEncSlice::initCtxMem( UInt i ) 72 { 73 for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++) 74 { 75 delete (*j); 76 } 77 CTXMem.clear(); 78 CTXMem.resize(i); 79 } 80 81 Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth ) 61 } 62 63 Void TEncSlice::create( Int iWidth, Int iHeight, ChromaFormat chromaFormat, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth ) 82 64 { 83 65 // create prediction picture … … 85 67 { 86 68 m_apcPicYuvPred = new TComPicYuv; 87 m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth);88 } 89 69 m_apcPicYuvPred->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth, true ); 70 } 71 90 72 // create residual picture 91 73 if( m_apcPicYuvResi == NULL ) 92 74 { 93 75 m_apcPicYuvResi = new TComPicYuv; 94 m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth);76 m_apcPicYuvResi->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth, true ); 95 77 } 96 78 } … … 105 87 m_apcPicYuvPred = NULL; 106 88 } 107 89 108 90 // destroy residual picture 109 91 if ( m_apcPicYuvResi ) … … 113 95 m_apcPicYuvResi = NULL; 114 96 } 115 97 116 98 // free lambda and QP arrays 117 if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; } 118 if ( m_pdRdPicQp ) { xFree( m_pdRdPicQp ); m_pdRdPicQp = NULL; } 119 if ( m_piRdPicQp ) { xFree( m_piRdPicQp ); m_piRdPicQp = NULL; } 120 121 if ( m_pcBufferSbacCoders ) 122 { 123 delete[] m_pcBufferSbacCoders; 124 } 125 if ( m_pcBufferBinCoderCABACs ) 126 { 127 delete[] m_pcBufferBinCoderCABACs; 128 } 129 if ( m_pcBufferLowLatSbacCoders ) 130 delete[] m_pcBufferLowLatSbacCoders; 131 if ( m_pcBufferLowLatBinCoderCABACs ) 132 delete[] m_pcBufferLowLatBinCoderCABACs; 99 if ( m_pdRdPicLambda ) 100 { 101 xFree( m_pdRdPicLambda ); 102 m_pdRdPicLambda = NULL; 103 } 104 if ( m_pdRdPicQp ) 105 { 106 xFree( m_pdRdPicQp ); 107 m_pdRdPicQp = NULL; 108 } 109 if ( m_piRdPicQp ) 110 { 111 xFree( m_piRdPicQp ); 112 m_piRdPicQp = NULL; 113 } 133 114 } 134 115 … … 137 118 m_pcCfg = pcEncTop; 138 119 m_pcListPic = pcEncTop->getListPic(); 139 120 140 121 m_pcGOPEncoder = pcEncTop->getGOPEncoder(); 141 122 m_pcCuEncoder = pcEncTop->getCuEncoder(); 142 123 m_pcPredSearch = pcEncTop->getPredSearch(); 143 124 144 125 m_pcEntropyCoder = pcEncTop->getEntropyCoder(); 145 m_pcCavlcCoder = pcEncTop->getCavlcCoder();146 126 m_pcSbacCoder = pcEncTop->getSbacCoder(); 147 127 m_pcBinCABAC = pcEncTop->getBinCABAC(); 148 128 m_pcTrQuant = pcEncTop->getTrQuant(); 149 150 m_pcBitCounter = pcEncTop->getBitCounter(); 129 151 130 m_pcRdCost = pcEncTop->getRdCost(); 152 131 m_pppcRDSbacCoder = pcEncTop->getRDSbacCoder(); 153 132 m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder(); 154 133 155 134 // create lambda and QP arrays 156 135 m_pdRdPicLambda = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 ); … … 169 148 m_pcRateCtrl = pcEncTop->getRateCtrl(); 170 149 #endif 171 } 150 151 } 152 153 154 155 Void 156 TEncSlice::setUpLambda(TComSlice* slice, const Double dLambda, Int iQP) 157 { 158 // store lambda 159 m_pcRdCost ->setLambda( dLambda, slice->getSPS()->getBitDepths() ); 160 161 // for RDO 162 // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma. 163 Double dLambdas[MAX_NUM_COMPONENT] = { dLambda }; 164 for(UInt compIdx=1; compIdx<MAX_NUM_COMPONENT; compIdx++) 165 { 166 const ComponentID compID=ComponentID(compIdx); 167 Int chromaQPOffset = slice->getPPS()->getQpOffset(compID) + slice->getSliceChromaQpDelta(compID); 168 Int qpc=(iQP + chromaQPOffset < 0) ? iQP : getScaledChromaQP(iQP + chromaQPOffset, m_pcCfg->getChromaFormatIdc()); 169 Double tmpWeight = pow( 2.0, (iQP-qpc)/3.0 ); // takes into account of the chroma qp mapping and chroma qp Offset 170 m_pcRdCost->setDistortionWeight(compID, tmpWeight); 171 dLambdas[compIdx]=dLambda/tmpWeight; 172 } 173 174 #if RDOQ_CHROMA_LAMBDA 175 // for RDOQ 176 m_pcTrQuant->setLambdas( dLambdas ); 177 #else 178 m_pcTrQuant->setLambda( dLambda ); 179 #endif 180 181 // For SAO 182 slice ->setLambdas( dLambdas ); 183 } 184 185 172 186 173 187 /** … … 181 195 \param pocCurr current POC 182 196 \param iNumPicRcvd number of received pictures 183 \param iTimeOffset POC offset for hierarchical structure 184 \param iDepth temporal layer depth 197 \param iGOPid POC offset for hierarchical structure 185 198 \param rpcSlice slice header class 186 \param pSPS SPS associated with the slice 187 \param pPPS PPS associated with the slice 199 \param isField true for field coding 188 200 */ 189 #if H_MV 190 Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComVPS* pVPS, TComSPS* pSPS, TComPPS *pPPS, Int layerId, bool isField ) 191 #else 192 Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, bool isField ) 201 202 #if NH_MV 203 Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iGOPid, TComSlice*& rpcSlice, TComVPS* pVPS, Int layerId, bool isField ) 204 #else 205 Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iGOPid, TComSlice*& rpcSlice, Bool isField ) 193 206 #endif 194 207 { 195 208 Double dQP; 196 209 Double dLambda; 197 210 198 211 rpcSlice = pcPic->getSlice(0); 199 212 200 #if H_MV213 #if NH_MV 201 214 rpcSlice->setVPS( pVPS ); 202 215 … … 204 217 rpcSlice->setViewId ( pVPS->getViewId ( layerId ) ); 205 218 rpcSlice->setViewIndex ( pVPS->getViewIndex ( layerId ) ); 206 #if H_3D219 #if NH_3D 207 220 rpcSlice->setIsDepth ( pVPS->getDepthId ( layerId ) != 0 ); 208 221 #endif 209 222 #endif 210 rpcSlice->setSPS( pSPS );211 rpcSlice->setPPS( pPPS );212 223 rpcSlice->setSliceBits(0); 213 224 rpcSlice->setPic( pcPic ); … … 215 226 rpcSlice->setPicOutputFlag( true ); 216 227 rpcSlice->setPOC( pocCurr ); 217 #if H_3D_IC228 #if NH_3D_IC 218 229 rpcSlice->setApplyIC( false ); 219 230 #endif … … 221 232 Int depth; 222 233 { 223 #if FIX_FIELD_DEPTH 234 224 235 Int poc = rpcSlice->getPOC(); 225 236 if(isField) 226 237 { 227 poc = (poc/2) %(m_pcCfg->getGOPSize()/2);238 poc = (poc/2) % (m_pcCfg->getGOPSize()/2); 228 239 } 229 240 else 230 241 { 231 poc = poc%m_pcCfg->getGOPSize(); 232 } 233 #else 234 Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize(); 235 #endif 242 poc = poc % m_pcCfg->getGOPSize(); 243 } 236 244 if ( poc == 0 ) 237 245 { … … 256 264 } 257 265 } 258 #if FIX_FIELD_DEPTH 259 #if HARMONIZE_GOP_FIRST_FIELD_COUPLE 260 if(poc != 0) 261 { 262 #endif 263 if(isField && rpcSlice->getPOC()%2 == 1) 264 { 265 depth ++; 266 } 267 #if HARMONIZE_GOP_FIRST_FIELD_COUPLE 268 } 269 #endif 270 #endif 271 } 272 266 267 if(m_pcCfg->getHarmonizeGopFirstFieldCoupleEnabled() && poc != 0) 268 { 269 if (isField && ((rpcSlice->getPOC() % 2) == 1)) 270 { 271 depth ++; 272 } 273 } 274 } 275 273 276 // slice type 274 #if H_MV277 #if NH_MV 275 278 SliceType eSliceTypeBaseView; 276 279 if( pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0 ) … … 289 292 #else 290 293 SliceType eSliceType; 291 294 292 295 eSliceType=B_SLICE; 293 #if EFFICIENT_FIELD_IRAP 294 if(!(isField && pocLast == 1)) 295 { 296 #endif // EFFICIENT_FIELD_IRAP 297 #if ALLOW_RECOVERY_POINT_AS_RAP 298 if(m_pcCfg->getDecodingRefreshType() == 3) 299 { 300 eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 301 } 302 else 303 { 304 eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 305 } 306 #else 307 eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 308 #endif 309 #if EFFICIENT_FIELD_IRAP 310 } 311 #endif 312 #endif 313 296 if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled()) 297 { 298 if(m_pcCfg->getDecodingRefreshType() == 3) 299 { 300 eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 301 } 302 else 303 { 304 eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 305 } 306 } 307 #endif 314 308 rpcSlice->setSliceType ( eSliceType ); 315 309 … … 317 311 // Non-referenced frame marking 318 312 // ------------------------------------------------------------------------------------------------------------------ 319 313 320 314 if(pocLast == 0) 321 315 { … … 324 318 else 325 319 { 326 #if 0 // Check this! H_MV320 #if 0 // Check this! NH_MV 327 321 rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_refPic); 328 322 #else … … 331 325 } 332 326 rpcSlice->setReferenced(true); 333 327 334 328 // ------------------------------------------------------------------------------------------------------------------ 335 329 // QP setting 336 330 // ------------------------------------------------------------------------------------------------------------------ 337 331 338 332 dQP = m_pcCfg->getQP(); 339 333 if(eSliceType!=I_SLICE) 340 334 { 341 if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffset Y() ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))342 { 343 #if H_MV335 if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA) ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag()))) 336 { 337 #if NH_MV 344 338 dQP += m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPOffset; 345 339 #else … … 348 342 } 349 343 } 350 344 351 345 // modify QP 352 346 Int* pdQPs = m_pcCfg->getdQPs(); … … 355 349 dQP += pdQPs[ rpcSlice->getPOC() ]; 356 350 } 351 352 if (m_pcCfg->getCostMode()==COST_LOSSLESS_CODING) 353 { 354 dQP=LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP; 355 m_pcCfg->setDeltaQpRD(0); 356 } 357 357 358 // ------------------------------------------------------------------------------------------------------------------ 358 359 // Lambda computation 359 360 // ------------------------------------------------------------------------------------------------------------------ 360 361 361 362 Int iQP; 362 363 Double dOrigQP = dQP; … … 367 368 // compute QP value 368 369 dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1); 369 370 370 371 // compute lambda value 371 372 Int NumberBFrames = ( m_pcCfg->getGOPSize() - 1 ); 372 373 Int SHIFT_QP = 12; 374 373 375 Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) ); 376 374 377 #if FULL_NBIT 375 Int bitdepth_luma_qp_scale = 6 * ( g_bitDepth- 8);378 Int bitdepth_luma_qp_scale = 6 * (rpcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8); 376 379 #else 377 380 Int bitdepth_luma_qp_scale = 0; … … 382 385 #endif 383 386 // Case #1: I or P-slices (key-frame) 384 #if H_MV387 #if NH_MV 385 388 Double dQPFactor; 386 389 if( eSliceType != I_SLICE ) … … 406 409 #endif 407 410 } 408 411 409 412 // if hadamard is used in ME process 410 413 if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE ) … … 412 415 dLambda *= 0.95; 413 416 } 414 415 iQP = max( - pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );417 418 iQP = max( -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) ); 416 419 417 420 m_pdRdPicLambda[iDQpIdx] = dLambda; … … 419 422 m_piRdPicQp [iDQpIdx] = iQP; 420 423 } 421 424 422 425 // obtain dQP = 0 case 423 426 dLambda = m_pdRdPicLambda[0]; 424 427 dQP = m_pdRdPicQp [0]; 425 428 iQP = m_piRdPicQp [0]; 426 429 427 430 if( rpcSlice->getSliceType( ) != I_SLICE ) 428 431 { 429 #if H_MV432 #if NH_MV 430 433 dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_temporalId ); 431 434 #else … … 434 437 } 435 438 436 // store lambda 437 m_pcRdCost ->setLambda( dLambda ); 438 439 #if H_3D_VSO 439 setUpLambda(rpcSlice, dLambda, iQP); 440 441 #if NH_3D_VSO 440 442 m_pcRdCost->setUseLambdaScaleVSO ( (m_pcCfg->getUseVSO() || m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->getIsDepth() ); 441 443 m_pcRdCost->setLambdaVSO ( dLambda * m_pcCfg->getLambdaScaleVSO() ); … … 456 458 #endif 457 459 458 // for RDO 459 // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma. 460 Double weight[2] = { 1.0, 1.0 }; 461 Int qpc; 462 Int chromaQPOffset; 463 464 chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb(); 465 qpc = Clip3( 0, 57, iQP + chromaQPOffset); 466 weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 ); // takes into account of the chroma qp mapping and chroma qp Offset 467 m_pcRdCost->setCbDistortionWeight(weight[0]); 468 469 chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr(); 470 qpc = Clip3( 0, 57, iQP + chromaQPOffset); 471 weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 ); // takes into account of the chroma qp mapping and chroma qp Offset 472 m_pcRdCost->setCrDistortionWeight(weight[1]); 473 474 const Double lambdaArray[3] = {dLambda, (dLambda / weight[0]), (dLambda / weight[1])}; 475 476 #if RDOQ_CHROMA_LAMBDA 477 // for RDOQ 478 m_pcTrQuant->setLambdas( lambdaArray ); 479 #else 480 m_pcTrQuant->setLambda( dLambda ); 481 #endif 482 483 // For SAO 484 rpcSlice->setLambdas( lambdaArray ); 485 486 #if HB_LAMBDA_FOR_LDC 460 if (m_pcCfg->getFastMEForGenBLowDelayEnabled()) 461 { 487 462 // restore original slice type 488 #if H_MV463 #if NH_MV 489 464 eSliceType = eSliceTypeBaseView; 490 465 if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' ) … … 493 468 } 494 469 #else 495 #if EFFICIENT_FIELD_IRAP 496 if(!(isField && pocLast == 1)) 497 { 498 #endif // EFFICIENT_FIELD_IRAP 499 #if ALLOW_RECOVERY_POINT_AS_RAP 500 if(m_pcCfg->getDecodingRefreshType() == 3) 501 { 502 eSliceType = (pocLast == 0 || (pocCurr) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 503 504 } 505 else 506 { 507 eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 508 } 509 #else 510 eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 511 #endif 512 #if EFFICIENT_FIELD_IRAP 513 } 514 #endif // EFFICIENT_FIELD_IRAP 470 if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled()) 471 { 472 if(m_pcCfg->getDecodingRefreshType() == 3) 473 { 474 eSliceType = (pocLast == 0 || (pocCurr) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 475 } 476 else 477 { 478 eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType; 479 480 } 481 } 515 482 #endif 516 483 517 484 rpcSlice->setSliceType ( eSliceType ); 518 #endif 519 485 } 486 520 487 if (m_pcCfg->getUseRecalculateQPAccordingToLambda()) 521 488 { 522 489 dQP = xGetQPValueAccordingToLambda( dLambda ); 523 iQP = max( - pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );524 } 525 526 rpcSlice->setSliceQp ( iQP );490 iQP = max( -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) ); 491 } 492 493 rpcSlice->setSliceQp ( iQP ); 527 494 #if ADAPTIVE_QP_SELECTION 528 rpcSlice->setSliceQpBase ( iQP ); 529 #endif 530 rpcSlice->setSliceQpDelta ( 0 ); 531 rpcSlice->setSliceQpDeltaCb ( 0 ); 532 rpcSlice->setSliceQpDeltaCr ( 0 ); 533 #if H_MV 495 rpcSlice->setSliceQpBase ( iQP ); 496 #endif 497 rpcSlice->setSliceQpDelta ( 0 ); 498 rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 ); 499 rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 ); 500 rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getPpsRangeExtension().getChromaQpOffsetListEnabledFlag() ); 501 #if NH_MV 534 502 rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive); 535 503 rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive); … … 545 513 rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 ); 546 514 rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 ); 547 } else 548 if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag()) 549 { 550 rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() ); 551 rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() ); 552 rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() ); 553 rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() ); 515 } 516 else if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag()) 517 { 518 rpcSlice->setDeblockingFilterOverrideFlag( rpcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() ); 519 rpcSlice->setDeblockingFilterDisable( rpcSlice->getPPS()->getPicDisableDeblockingFilterFlag() ); 554 520 if ( !rpcSlice->getDeblockingFilterDisable()) 555 521 { 556 if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE) 557 { 558 #if H_MV 559 rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() ); 560 rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() ); 522 if ( rpcSlice->getDeblockingFilterOverrideFlag() && eSliceType!=I_SLICE) 523 { 524 #if NH_MV 561 525 rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() ); 562 526 rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() ); 563 527 #else 564 rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );565 rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );566 528 rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() ); 567 529 rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() ); … … 570 532 else 571 533 { 572 rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() ); 573 rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() ); 574 rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() ); 575 rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() ); 534 rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() ); 535 rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() ); 576 536 } 577 537 } … … 586 546 587 547 rpcSlice->setDepth ( depth ); 588 589 #if H_MV548 549 #if NH_MV 590 550 pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId ); 591 551 #else … … 600 560 assert( m_apcPicYuvPred ); 601 561 assert( m_apcPicYuvResi ); 602 562 603 563 pcPic->setPicYuvPred( m_apcPicYuvPred ); 604 564 pcPic->setPicYuvResi( m_apcPicYuvResi ); … … 607 567 rpcSlice->setSliceSegmentMode ( m_pcCfg->getSliceSegmentMode() ); 608 568 rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() ); 609 #if !H_3D 569 #if NH_3D_IV_MERGE 570 #else 610 571 rpcSlice->setMaxNumMergeCand ( m_pcCfg->getMaxNumMergeCand() ); 611 572 #endif 612 xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );613 573 } 614 574 … … 622 582 slice->setSliceQpBase ( sliceQP ); 623 583 #endif 624 m_pcRdCost ->setLambda( lambda ); 625 // for RDO 626 // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma. 627 Double weight[2] = { 1.0, 1.0 }; 628 Int qpc; 629 Int chromaQPOffset; 630 631 chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb(); 632 qpc = Clip3( 0, 57, sliceQP + chromaQPOffset); 633 weight[0] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 ); // takes into account of the chroma qp mapping and chroma qp Offset 634 m_pcRdCost->setCbDistortionWeight(weight[0]); 635 636 chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr(); 637 qpc = Clip3( 0, 57, sliceQP + chromaQPOffset); 638 weight[1] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 ); // takes into account of the chroma qp mapping and chroma qp Offset 639 m_pcRdCost->setCrDistortionWeight(weight[1]); 640 641 const Double lambdaArray[3] = {lambda, (lambda / weight[0]), (lambda / weight[1])}; 642 643 #if RDOQ_CHROMA_LAMBDA 644 // for RDOQ 645 m_pcTrQuant->setLambdas( lambdaArray ); 646 #else 647 m_pcTrQuant->setLambda( lambda ); 648 #endif 649 650 // For SAO 651 slice->setLambdas( lambdaArray ); 652 } 584 setUpLambda(slice, lambda, sliceQP); 585 } 586 653 587 // ==================================================================================================================== 654 588 // Public member functions … … 663 597 Int iMaxSR = m_pcCfg->getSearchRange(); 664 598 Int iNumPredDir = pcSlice->isInterP() ? 1 : 2; 665 599 666 600 for (Int iDir = 0; iDir <= iNumPredDir; iDir++) 667 601 { … … 678 612 679 613 /** 680 - multi-loop slice encoding for different slice QP681 . 682 \param rpcPic picture class614 Multi-loop slice encoding for different slice QP 615 616 \param pcPic picture class 683 617 */ 684 Void TEncSlice::precompressSlice( TComPic* & rpcPic )618 Void TEncSlice::precompressSlice( TComPic* pcPic ) 685 619 { 686 620 // if deltaQP RD is not used, simply return … … 694 628 printf( "\nMultiple QP optimization is not allowed when rate control is enabled." ); 695 629 assert(0); 696 } 697 698 TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx()); 630 return; 631 } 632 633 TComSlice* pcSlice = pcPic->getSlice(getSliceIdx()); 634 635 if (pcSlice->getDependentSliceSegmentFlag()) 636 { 637 // if this is a dependent slice segment, then it was optimised 638 // when analysing the entire slice. 639 return; 640 } 641 642 if (pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES) 643 { 644 // TODO: investigate use of average cost per CTU so that this Slice Mode can be used. 645 printf( "\nUnable to optimise Slice-level QP if Slice Mode is set to FIXED_NUMBER_OF_BYTES\n" ); 646 assert(0); 647 return; 648 } 649 650 699 651 Double dPicRdCostBest = MAX_DOUBLE; 700 652 UInt uiQpIdxBest = 0; 701 653 702 654 Double dFrameLambda; 703 655 #if FULL_NBIT 704 Int SHIFT_QP = 12 + 6 * ( g_bitDepth- 8);656 Int SHIFT_QP = 12 + 6 * (pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8); 705 657 #else 706 658 Int SHIFT_QP = 12; 707 659 #endif 708 660 709 661 // set frame lambda 710 662 if (m_pcCfg->getGOPSize() > 1) … … 717 669 } 718 670 m_pcRdCost ->setFrameLambda(dFrameLambda); 719 671 720 672 // for each QP candidate 721 673 for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ ) … … 725 677 pcSlice ->setSliceQpBase ( m_piRdPicQp [uiQpIdx] ); 726 678 #endif 727 m_pcRdCost ->setLambda ( m_pdRdPicLambda[uiQpIdx] ); 728 // for RDO 729 // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma. 730 Int iQP = m_piRdPicQp [uiQpIdx]; 731 Double weight[2] = { 1.0, 1.0 }; 732 Int qpc; 733 Int chromaQPOffset; 734 735 chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb(); 736 qpc = Clip3( 0, 57, iQP + chromaQPOffset); 737 weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 ); // takes into account of the chroma qp mapping and chroma qp Offset 738 m_pcRdCost->setCbDistortionWeight(weight[0]); 739 740 chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr(); 741 qpc = Clip3( 0, 57, iQP + chromaQPOffset); 742 weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 ); // takes into account of the chroma qp mapping and chroma qp Offset 743 m_pcRdCost->setCrDistortionWeight(weight[1]); 744 745 const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdx], (m_pdRdPicLambda[uiQpIdx] / weight[0]), (m_pdRdPicLambda[uiQpIdx] / weight[1])}; 746 #if RDOQ_CHROMA_LAMBDA 747 // for RDOQ 748 m_pcTrQuant->setLambdas( lambdaArray ); 749 #else 750 m_pcTrQuant ->setLambda ( m_pdRdPicLambda[uiQpIdx] ); 751 #endif 752 // For SAO 753 pcSlice->setLambdas( lambdaArray ); 754 679 setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdx], m_piRdPicQp [uiQpIdx]); 680 755 681 // try compress 756 compressSlice ( rpcPic ); 757 758 Double dPicRdCost; 759 #if H_3D_VSO 682 compressSlice ( pcPic, true, m_pcCfg->getFastDeltaQp()); 683 684 #if NH_3D_VSO 760 685 Dist64 uiPicDist = m_uiPicDist; 761 686 #else 762 UInt64 uiPicDist = m_uiPicDist; 763 #endif 764 UInt64 uiALFBits = 0; 765 766 m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits ); 767 687 UInt64 uiPicDist = m_uiPicDist; // Distortion, as calculated by compressSlice. 688 // NOTE: This distortion is the chroma-weighted SSE distortion for the slice. 689 // Previously a standard SSE distortion was calculated (for the entire frame). 690 // Which is correct? 691 692 // TODO: Update loop filter, SAO and distortion calculation to work on one slice only. 693 // m_pcGOPEncoder->preLoopFilterPicAll( pcPic, uiPicDist ); 694 695 #endif 696 768 697 // compute RD cost and choose the best 769 dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);698 Double dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits, uiPicDist, true, DF_SSE_FRAME); // NOTE: Is the 'true' parameter really necessary? 770 699 #if H_3D 771 700 // Above calculation need to be fixed for VSO, including frameLambda value. 772 701 #endif 773 702 774 703 if ( dPicRdCost < dPicRdCostBest ) 775 704 { … … 778 707 } 779 708 } 780 709 781 710 // set best values 782 711 pcSlice ->setSliceQp ( m_piRdPicQp [uiQpIdxBest] ); … … 784 713 pcSlice ->setSliceQpBase ( m_piRdPicQp [uiQpIdxBest] ); 785 714 #endif 786 m_pcRdCost ->setLambda ( m_pdRdPicLambda[uiQpIdxBest] ); 787 // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma. 788 Int iQP = m_piRdPicQp [uiQpIdxBest]; 789 Double weight[2] = { 1.0, 1.0 }; 790 Int qpc; 791 Int chromaQPOffset; 792 793 chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb(); 794 qpc = Clip3( 0, 57, iQP + chromaQPOffset); 795 weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 ); // takes into account of the chroma qp mapping and chroma qp Offset 796 m_pcRdCost->setCbDistortionWeight(weight[0]); 797 798 chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr(); 799 qpc = Clip3( 0, 57, iQP + chromaQPOffset); 800 weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 ); // takes into account of the chroma qp mapping and chroma qp Offset 801 m_pcRdCost->setCrDistortionWeight(weight[1]); 802 803 const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdxBest], (m_pdRdPicLambda[uiQpIdxBest] / weight[0]), (m_pdRdPicLambda[uiQpIdxBest] / weight[1])}; 804 #if RDOQ_CHROMA_LAMBDA 805 // for RDOQ 806 m_pcTrQuant->setLambdas( lambdaArray ); 807 #else 808 m_pcTrQuant ->setLambda ( m_pdRdPicLambda[uiQpIdxBest] ); 809 #endif 810 // For SAO 811 pcSlice->setLambdas( lambdaArray ); 812 } 813 814 /** \param rpcPic picture class 715 setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdxBest], m_piRdPicQp [uiQpIdxBest]); 716 } 717 718 Void TEncSlice::calCostSliceI(TComPic* pcPic) // TODO: this only analyses the first slice segment. What about the others? 719 { 720 Double iSumHadSlice = 0; 721 TComSlice * const pcSlice = pcPic->getSlice(getSliceIdx()); 722 const TComSPS &sps = *(pcSlice->getSPS()); 723 const Int shift = sps.getBitDepth(CHANNEL_TYPE_LUMA)-8; 724 const Int offset = (shift>0)?(1<<(shift-1)):0; 725 726 pcSlice->setSliceSegmentBits(0); 727 728 UInt startCtuTsAddr, boundingCtuTsAddr; 729 xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic ); 730 731 for( UInt ctuTsAddr = startCtuTsAddr, ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr); 732 ctuTsAddr < boundingCtuTsAddr; 733 ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(++ctuTsAddr) ) 734 { 735 // initialize CU encoder 736 TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr ); 737 pCtu->initCtu( pcPic, ctuRsAddr ); 738 739 Int height = min( sps.getMaxCUHeight(),sps.getPicHeightInLumaSamples() - ctuRsAddr / pcPic->getFrameWidthInCtus() * sps.getMaxCUHeight() ); 740 Int width = min( sps.getMaxCUWidth(), sps.getPicWidthInLumaSamples() - ctuRsAddr % pcPic->getFrameWidthInCtus() * sps.getMaxCUWidth() ); 741 742 Int iSumHad = m_pcCuEncoder->updateCtuDataISlice(pCtu, width, height); 743 744 (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra=(iSumHad+offset)>>shift; 745 iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra; 746 747 } 748 m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice); 749 } 750 751 /** \param pcPic picture class 815 752 */ 816 Void TEncSlice::calCostSliceI(TComPic*& rpcPic) 817 { 818 UInt uiCUAddr; 819 UInt uiStartCUAddr; 820 UInt uiBoundingCUAddr; 821 Int iSumHad, shift = g_bitDepthY-8, offset = (shift>0)?(1<<(shift-1)):0;; 822 Double iSumHadSlice = 0; 823 824 rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0); 825 TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx()); 826 xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false ); 827 828 UInt uiEncCUOrder; 829 uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 830 for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU(); 831 uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU(); 832 uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) ) 833 { 834 // initialize CU encoder 835 TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr ); 836 pcCU->initCU( rpcPic, uiCUAddr ); 837 838 Int height = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() ); 839 Int width = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() ); 840 841 iSumHad = m_pcCuEncoder->updateLCUDataISlice(pcCU, uiCUAddr, width, height); 842 843 (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra=(iSumHad+offset)>>shift; 844 iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr)).m_costIntra; 845 846 } 847 m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice); 848 } 849 850 Void TEncSlice::compressSlice( TComPic*& rpcPic ) 851 { 852 UInt uiCUAddr; 853 UInt uiStartCUAddr; 854 UInt uiBoundingCUAddr; 855 rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0); 856 TEncBinCABAC* pppcRDSbacCoder = NULL; 857 TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx()); 858 xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false ); 753 Void TEncSlice::compressSlice( TComPic* pcPic, const Bool bCompressEntireSlice, const Bool bFastDeltaQP ) 754 { 755 // if bCompressEntireSlice is true, then the entire slice (not slice segment) is compressed, 756 // effectively disabling the slice-segment-mode. 757 758 UInt startCtuTsAddr; 759 UInt boundingCtuTsAddr; 760 TComSlice* const pcSlice = pcPic->getSlice(getSliceIdx()); 761 pcSlice->setSliceSegmentBits(0); 762 xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic ); 763 if (bCompressEntireSlice) 764 { 765 boundingCtuTsAddr = pcSlice->getSliceCurEndCtuTsAddr(); 766 pcSlice->setSliceSegmentCurEndCtuTsAddr(boundingCtuTsAddr); 767 } 768 769 // initialize cost values - these are used by precompressSlice (they should be parameters). 770 m_uiPicTotalBits = 0; 771 m_dPicRdCost = 0; // NOTE: This is a write-only variable! 772 m_uiPicDist = 0; 773 774 m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); 775 m_pcEntropyCoder->resetEntropy ( pcSlice ); 776 777 TEncBinCABAC* pRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf(); 778 pRDSbacCoder->setBinCountingEnableFlag( false ); 779 pRDSbacCoder->setBinsCoded( 0 ); 780 781 TComBitCounter tempBitCounter; 782 const UInt frameWidthInCtus = pcPic->getPicSym()->getFrameWidthInCtus(); 859 783 860 // initialize cost values 861 m_uiPicTotalBits = 0; 862 m_dPicRdCost = 0; 863 m_uiPicDist = 0; 864 865 // set entropy coder 866 m_pcSbacCoder->init( m_pcBinCABAC ); 867 m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice ); 868 m_pcEntropyCoder->resetEntropy (); 869 m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder); 870 pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf(); 871 pppcRDSbacCoder->setBinCountingEnableFlag( false ); 872 pppcRDSbacCoder->setBinsCoded( 0 ); 873 784 m_pcCuEncoder->setFastDeltaQp(bFastDeltaQP); 785 874 786 //------------------------------------------------------------------------------ 875 787 // Weighted Prediction parameters estimation. … … 881 793 } 882 794 883 Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());795 const Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred()); 884 796 885 797 if ( bWp_explicit ) … … 888 800 // Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet. 889 801 //------------------------------------------------------------------------------ 890 if ( pcSlice->getSliceMode()== 2 || pcSlice->getSliceSegmentMode()==2)802 if ( pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES || pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES ) 891 803 { 892 804 printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0); … … 894 806 895 807 xEstimateWPParamSlice( pcSlice ); 896 pcSlice->initWpScaling( );808 pcSlice->initWpScaling(pcSlice->getSPS()); 897 809 898 810 // check WP on/off … … 901 813 902 814 #if ADAPTIVE_QP_SELECTION 903 if( m_pcCfg->getUseAdaptQpSelect() ) 904 { 905 m_pcTrQuant->clearSliceARLCnt(); 815 if( m_pcCfg->getUseAdaptQpSelect() && !(pcSlice->getDependentSliceSegmentFlag())) 816 { 817 // TODO: this won't work with dependent slices: they do not have their own QP. Check fix to mask clause execution with && !(pcSlice->getDependentSliceSegmentFlag()) 818 m_pcTrQuant->clearSliceARLCnt(); // TODO: this looks wrong for multiple slices - the results of all but the last slice will be cleared before they are used (all slices compressed, and then all slices encoded) 906 819 if(pcSlice->getSliceType()!=I_SLICE) 907 820 { … … 911 824 } 912 825 #endif 913 TEncTop* pcEncTop = (TEncTop*) m_pcCfg; 914 TEncSbac**** ppppcRDSbacCoders = pcEncTop->getRDSbacCoders(); 915 TComBitCounter* pcBitCounters = pcEncTop->getBitCounters(); 916 Int iNumSubstreams = 1; 917 UInt uiTilesAcross = 0; 918 #if H_3D_IC 919 if ( pcEncTop->getViewIndex() && pcEncTop->getUseIC() && 826 827 #if NH_3D_IC 828 if ( m_pcCfg->getViewIndex() && m_pcCfg->getUseIC() && 920 829 !( ( pcSlice->getSliceType() == P_SLICE && pcSlice->getPPS()->getUseWP() ) || ( pcSlice->getSliceType() == B_SLICE && pcSlice->getPPS()->getWPBiPred() ) ) 921 830 ) 922 831 { 923 pcSlice ->xSetApplyIC( pcEncTop->getUseICLowLatencyEnc());832 pcSlice ->xSetApplyIC(m_pcCfg->getUseICLowLatencyEnc()); 924 833 if ( pcSlice->getApplyIC() ) 925 834 { … … 928 837 } 929 838 #endif 930 iNumSubstreams = pcSlice->getPPS()->getNumSubstreams(); 931 uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1; 932 delete[] m_pcBufferSbacCoders; 933 delete[] m_pcBufferBinCoderCABACs; 934 m_pcBufferSbacCoders = new TEncSbac [uiTilesAcross]; 935 m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross]; 936 for (Int ui = 0; ui < uiTilesAcross; ui++) 937 { 938 m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] ); 939 } 940 for (UInt ui = 0; ui < uiTilesAcross; ui++) 941 { 942 m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]); //init. state 943 } 944 945 for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization 946 { 947 ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]); 948 } 949 delete[] m_pcBufferLowLatSbacCoders; 950 delete[] m_pcBufferLowLatBinCoderCABACs; 951 m_pcBufferLowLatSbacCoders = new TEncSbac [uiTilesAcross]; 952 m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross]; 953 for (Int ui = 0; ui < uiTilesAcross; ui++) 954 { 955 m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] ); 956 } 957 for (UInt ui = 0; ui < uiTilesAcross; ui++) 958 m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]); //init. state 959 960 UInt uiWidthInLCUs = rpcPic->getPicSym()->getFrameWidthInCU(); 961 //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU(); 962 UInt uiCol=0, uiLin=0, uiSubStrm=0; 963 UInt uiTileCol = 0; 964 UInt uiTileStartLCU = 0; 965 UInt uiTileLCUX = 0; 966 Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag(); 967 uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 968 uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr(); 969 if( depSliceSegmentsEnabled ) 970 { 971 if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU)) 972 { 973 if( m_pcCfg->getWaveFrontsynchro() ) 974 { 975 uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); 976 m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] ); 977 Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles(); 978 uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 979 uiLin = uiCUAddr / uiWidthInLCUs; 980 uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile 981 + uiLin%iNumSubstreamsPerTile; 982 if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs ) 983 { 984 uiTileLCUX = uiTileStartLCU % uiWidthInLCUs; 985 uiCol = uiCUAddr % uiWidthInLCUs; 986 if(uiCol==uiTileStartLCU) 987 { 988 CTXMem[0]->loadContexts(m_pcSbacCoder); 989 } 990 } 991 } 992 m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] ); 993 ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] ); 994 } 995 else 996 { 997 if(m_pcCfg->getWaveFrontsynchro()) 998 { 999 CTXMem[1]->loadContexts(m_pcSbacCoder); 1000 } 1001 CTXMem[0]->loadContexts(m_pcSbacCoder); 1002 } 1003 } 1004 1005 // for every CU in slice 1006 #if H_3D 839 840 841 842 // Adjust initial state if this is the start of a dependent slice. 843 { 844 const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr); 845 const UInt currentTileIdx = pcPic->getPicSym()->getTileIdxMap(ctuRsAddr); 846 const TComTile *pCurrentTile = pcPic->getPicSym()->getTComTile(currentTileIdx); 847 const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr(); 848 if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile ) 849 { 850 // This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used. 851 if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getWaveFrontsynchro() ) 852 { 853 m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_lastSliceSegmentEndContextState ); 854 } 855 } 856 } 857 858 // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment) 859 #if NH_3D_VSO 1007 860 Int iLastPosY = -1; 1008 861 #endif 1009 UInt uiEncCUOrder; 1010 for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU(); 1011 uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU(); 1012 uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) ) 1013 { 1014 // initialize CU encoder 1015 TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr ); 1016 pcCU->initCU( rpcPic, uiCUAddr ); 1017 #if H_3D_VSO 862 863 for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr ) 864 { 865 const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr); 866 // initialize CTU encoder 867 TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr ); 868 pCtu->initCtu( pcPic, ctuRsAddr ); 869 #if NH_3D_VSO 1018 870 if ( m_pcRdCost->getUseRenModel() ) 1019 871 { … … 1021 873 Int iCurPosX; 1022 874 Int iCurPosY; 1023 p cCU->getPosInPic(0, iCurPosX, iCurPosY );875 pCtu->getPosInPic(0, iCurPosX, iCurPosY ); 1024 876 if ( iCurPosY != iLastPosY ) 1025 877 { 1026 878 iLastPosY = iCurPosY; 1027 pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY ); 1028 } 1029 } 1030 #endif 1031 // inherit from TR if necessary, select substream to use. 1032 uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in? 1033 uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr(); 1034 uiTileLCUX = uiTileStartLCU % uiWidthInLCUs; 1035 //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr(); 1036 uiCol = uiCUAddr % uiWidthInLCUs; 1037 uiLin = uiCUAddr / uiWidthInLCUs; 1038 if (pcSlice->getPPS()->getNumSubstreams() > 1) 1039 { 1040 // independent tiles => substreams are "per tile". iNumSubstreams has already been multiplied. 1041 Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles(); 1042 uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile 1043 + uiLin%iNumSubstreamsPerTile; 879 TEncTop* pcEncTop = (TEncTop*) m_pcCfg; // Fix this later. 880 pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY, pcSlice->getSPS()->getMaxCUHeight() ); 881 } 882 } 883 #endif 884 885 // update CABAC state 886 const UInt firstCtuRsAddrOfTile = pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr))->getFirstCtuRsAddr(); 887 const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus; 888 const UInt ctuXPosInCtus = ctuRsAddr % frameWidthInCtus; 889 890 if (ctuRsAddr == firstCtuRsAddrOfTile) 891 { 892 m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice); 893 } 894 else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getWaveFrontsynchro()) 895 { 896 // reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile). 897 m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice); 898 // Sync if the Top-Right is available. 899 TComDataCU *pCtuUp = pCtu->getCtuAbove(); 900 if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus) ) 901 { 902 TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 ); 903 if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) ) 904 { 905 // Top-Right is available, we use it. 906 m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_entropyCodingSyncContextState ); 907 } 908 } 909 } 910 911 // set go-on entropy coder (used for all trial encodings - the cu encoder and encoder search also have a copy of the same pointer) 912 m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder ); 913 m_pcEntropyCoder->setBitstream( &tempBitCounter ); 914 tempBitCounter.resetBits(); 915 m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); // this copy is not strictly necessary here, but indicates that the GoOnSbacCoder 916 // is reset to a known state before every decision process. 917 918 ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true); 919 920 Double oldLambda = m_pcRdCost->getLambda(); 921 if ( m_pcCfg->getUseRateCtrl() ) 922 { 923 Int estQP = pcSlice->getSliceQp(); 924 Double estLambda = -1.0; 925 Double bpp = -1.0; 926 927 if ( ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() ) 928 { 929 estQP = pcSlice->getSliceQp(); 1044 930 } 1045 931 else 1046 932 { 1047 // dependent tiles => substreams are "per frame".1048 uiSubStrm = uiLin % iNumSubstreams;1049 }1050 if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())1051 {1052 // We'll sync if the TR is available.1053 TComDataCU *pcCUUp = pcCU->getCUAbove();1054 UInt uiWidthInCU = rpcPic->getFrameWidthInCU();1055 UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);1056 TComDataCU *pcCUTR = NULL;1057 if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU) )1058 {1059 pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );1060 }1061 if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||1062 (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||1063 ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))1064 )1065 )1066 {1067 // TR not available.1068 }1069 else1070 {1071 // TR is available, we use it.1072 ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );1073 }1074 }1075 m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code1076 1077 // reset the entropy coder1078 if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() && // must be first CU of tile1079 uiCUAddr!=0 && // cannot be first CU of picture1080 uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&1081 uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU()) // cannot be first CU of slice1082 {1083 SliceType sliceType = pcSlice->getSliceType();1084 if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)1085 {1086 sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();1087 }1088 m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );1089 m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );1090 m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );1091 m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );1092 }1093 1094 // set go-on entropy coder1095 m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );1096 m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );1097 1098 ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);1099 1100 Double oldLambda = m_pcRdCost->getLambda();1101 if ( m_pcCfg->getUseRateCtrl() )1102 {1103 Int estQP = pcSlice->getSliceQp();1104 Double estLambda = -1.0;1105 Double bpp = -1.0;1106 1107 if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )1108 {1109 estQP = pcSlice->getSliceQp();1110 }1111 else1112 {1113 933 #if KWU_RC_MADPRED_E0227 1114 934 if(pcSlice->getLayerId() != 0 && m_pcCfg->getUseDepthMADPred() && !pcSlice->getIsDepth()) … … 1129 949 { 1130 950 #endif 1131 1132 if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)1133 1134 1135 1136 1137 1138 1139 1140 951 bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType()); 952 if ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE) 953 { 954 estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP); 955 } 956 else 957 { 958 estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp ); 959 estQP = m_pcRateCtrl->getRCPic()->getLCUEstQP ( estLambda, pcSlice->getSliceQp() ); 960 } 1141 961 #if KWU_RC_MADPRED_E0227 1142 962 estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp ); 1143 963 estQP = m_pcRateCtrl->getRCPic()->getLCUEstQP ( estLambda, pcSlice->getSliceQp() ); 1144 964 #endif 1145 estQP = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP ); 1146 1147 m_pcRdCost->setLambda(estLambda); 965 966 estQP = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP ); 967 968 m_pcRdCost->setLambda(estLambda, pcSlice->getSPS()->getBitDepths()); 969 1148 970 #if RDOQ_CHROMA_LAMBDA 1149 1150 Double weight=m_pcRdCost->getChromaWeight();1151 const Double lambdaArray[ 3] = { estLambda, (estLambda / weight), (estLambda / weight)};971 // set lambda for RDOQ 972 const Double chromaLambda = estLambda / m_pcRdCost->getChromaWeight(); 973 const Double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda }; 1152 974 m_pcTrQuant->setLambdas( lambdaArray ); 1153 975 #else 1154 1155 #endif 1156 1157 1158 976 m_pcTrQuant->setLambda( estLambda ); 977 #endif 978 } 979 980 m_pcRateCtrl->setRCQP( estQP ); 1159 981 #if ADAPTIVE_QP_SELECTION 1160 pcCU->getSlice()->setSliceQpBase( estQP ); 1161 #endif 1162 } 1163 // run CU encoder 1164 m_pcCuEncoder->compressCU( pcCU ); 1165 1166 // restore entropy coder to an initial stage 1167 m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice ); 1168 m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] ); 1169 m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] ); 1170 m_pcBitCounter = &pcBitCounters[uiSubStrm]; 1171 pppcRDSbacCoder->setBinCountingEnableFlag( true ); 1172 m_pcBitCounter->resetBits(); 1173 pppcRDSbacCoder->setBinsCoded( 0 ); 1174 m_pcCuEncoder->encodeCU( pcCU ); 1175 1176 pppcRDSbacCoder->setBinCountingEnableFlag( false ); 1177 if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3) 1178 { 1179 pcSlice->setNextSlice( true ); 1180 break; 1181 } 1182 if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr()) 1183 { 1184 pcSlice->setNextSliceSegment( true ); 1185 break; 1186 } 1187 1188 ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); 1189 //Store probabilties of second LCU in line into buffer 1190 if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro()) 1191 { 1192 m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]); 1193 } 1194 1195 if ( m_pcCfg->getUseRateCtrl() ) 1196 { 982 pCtu->getSlice()->setSliceQpBase( estQP ); 983 #endif 984 } 985 986 // run CTU trial encoder 987 m_pcCuEncoder->compressCtu( pCtu ); 988 989 990 // All CTU decisions have now been made. Restore entropy coder to an initial stage, ready to make a true encode, 991 // which will result in the state of the contexts being correct. It will also count up the number of bits coded, 992 // which is used if there is a limit of the number of bytes per slice-segment. 993 994 m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); 995 m_pcEntropyCoder->setBitstream( &tempBitCounter ); 996 pRDSbacCoder->setBinCountingEnableFlag( true ); 997 m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetBits(); 998 pRDSbacCoder->setBinsCoded( 0 ); 999 1000 // encode CTU and calculate the true bit counters. 1001 m_pcCuEncoder->encodeCtu( pCtu ); 1002 1003 1004 pRDSbacCoder->setBinCountingEnableFlag( false ); 1005 1006 const Int numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits(); 1007 1008 // Calculate if this CTU puts us over slice bit size. 1009 // cannot terminate if current slice/slice-segment would be 0 Ctu in size, 1010 const UInt validEndOfSliceCtuTsAddr = ctuTsAddr + (ctuTsAddr == startCtuTsAddr ? 1 : 0); 1011 // Set slice end parameter 1012 if(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceBits()+numberOfWrittenBits > (pcSlice->getSliceArgument()<<3)) 1013 { 1014 pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr); 1015 pcSlice->setSliceCurEndCtuTsAddr(validEndOfSliceCtuTsAddr); 1016 boundingCtuTsAddr=validEndOfSliceCtuTsAddr; 1017 } 1018 else if((!bCompressEntireSlice) && pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+numberOfWrittenBits > (pcSlice->getSliceSegmentArgument()<<3)) 1019 { 1020 pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr); 1021 boundingCtuTsAddr=validEndOfSliceCtuTsAddr; 1022 } 1023 1024 if (boundingCtuTsAddr <= ctuTsAddr) 1025 { 1026 break; 1027 } 1028 1029 pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) ); 1030 pcSlice->setSliceSegmentBits(pcSlice->getSliceSegmentBits()+numberOfWrittenBits); 1031 1032 // Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled. 1033 if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getWaveFrontsynchro()) 1034 { 1035 m_entropyCodingSyncContextState.loadContexts(m_pppcRDSbacCoder[0][CI_CURR_BEST]); 1036 } 1037 1038 1039 if ( m_pcCfg->getUseRateCtrl() ) 1040 { 1197 1041 #if KWU_RC_MADPRED_E0227 1198 1042 UInt SAD = m_pcCuEncoder->getLCUPredictionSAD(); … … 1204 1048 #endif 1205 1049 1206 Int actualQP = g_RCInvalidQPValue; 1207 Double actualLambda = m_pcRdCost->getLambda(); 1208 Int actualBits = pcCU->getTotalBits(); 1209 Int numberOfEffectivePixels = 0; 1210 for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ ) 1050 Int actualQP = g_RCInvalidQPValue; 1051 Double actualLambda = m_pcRdCost->getLambda(); 1052 Int actualBits = pCtu->getTotalBits(); 1053 Int numberOfEffectivePixels = 0; 1054 for ( Int idx = 0; idx < pcPic->getNumPartitionsInCtu(); idx++ ) 1055 { 1056 if ( pCtu->getPredictionMode( idx ) != NUMBER_OF_PREDICTION_MODES && ( !pCtu->isSkipped( idx ) ) ) 1211 1057 { 1212 if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) ) 1213 { 1214 numberOfEffectivePixels = numberOfEffectivePixels + 16; 1215 break; 1216 } 1058 numberOfEffectivePixels = numberOfEffectivePixels + 16; 1059 break; 1217 1060 } 1218 1219 if ( numberOfEffectivePixels == 0 ) 1220 { 1221 actualQP = g_RCInvalidQPValue; 1222 } 1223 else 1224 { 1225 actualQP = pcCU->getQP( 0 ); 1226 } 1227 m_pcRdCost->setLambda(oldLambda); 1228 1229 m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 1230 pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() ); 1231 } 1232 1233 m_uiPicTotalBits += pcCU->getTotalBits(); 1234 m_dPicRdCost += pcCU->getTotalCost(); 1235 m_uiPicDist += pcCU->getTotalDistortion(); 1236 } 1237 if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled) 1238 { 1239 pcSlice->setNextSlice( true ); 1240 } 1241 if(m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES || m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES) 1242 { 1243 if(pcSlice->getSliceCurEndCUAddr()<=pcSlice->getSliceSegmentCurEndCUAddr()) 1244 { 1245 pcSlice->setNextSlice( true ); 1246 } 1247 else 1248 { 1249 pcSlice->setNextSliceSegment( true ); 1250 } 1251 } 1252 if( depSliceSegmentsEnabled ) 1253 { 1254 if (m_pcCfg->getWaveFrontsynchro()) 1255 { 1256 CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU 1257 } 1258 CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice 1259 } 1260 xRestoreWPparam( pcSlice ); 1261 } 1262 1263 /** 1264 \param rpcPic picture class 1265 \retval rpcBitstream bitstream class 1266 */ 1267 Void TEncSlice::encodeSlice ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams ) 1268 { 1269 UInt uiCUAddr; 1270 UInt uiStartCUAddr; 1271 UInt uiBoundingCUAddr; 1272 TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx()); 1273 1274 uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr(); 1275 uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr(); 1276 // choose entropy coder 1277 { 1278 m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC ); 1279 m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice ); 1280 } 1281 1282 m_pcCuEncoder->setBitCounter( NULL ); 1283 m_pcBitCounter = NULL; 1284 // Appropriate substream bitstream is switched later. 1285 // for every CU 1061 } 1062 1063 if ( numberOfEffectivePixels == 0 ) 1064 { 1065 actualQP = g_RCInvalidQPValue; 1066 } 1067 else 1068 { 1069 actualQP = pCtu->getQP( 0 ); 1070 } 1071 m_pcRdCost->setLambda(oldLambda, pcSlice->getSPS()->getBitDepths()); 1072 m_pcRateCtrl->getRCPic()->updateAfterCTU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, 1073 pCtu->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() ); 1074 } 1075 1076 m_uiPicTotalBits += pCtu->getTotalBits(); 1077 m_dPicRdCost += pCtu->getTotalCost(); 1078 m_uiPicDist += pCtu->getTotalDistortion(); 1079 } 1080 1081 // store context state at the end of this slice-segment, in case the next slice is a dependent slice and continues using the CABAC contexts. 1082 if( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() ) 1083 { 1084 m_lastSliceSegmentEndContextState.loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice 1085 } 1086 1087 // stop use of temporary bit counter object. 1088 m_pppcRDSbacCoder[0][CI_CURR_BEST]->setBitstream(NULL); 1089 m_pcRDGoOnSbacCoder->setBitstream(NULL); // stop use of tempBitCounter. 1090 1091 // TODO: optimise cabac_init during compress slice to improve multi-slice operation 1092 //if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag()) 1093 //{ 1094 // m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx(); 1095 //} 1096 //else 1097 //{ 1098 // m_encCABACTableIdx = pcSlice->getSliceType(); 1099 //} 1100 } 1101 1102 Void TEncSlice::encodeSlice ( TComPic* pcPic, TComOutputBitstream* pcSubstreams, UInt &numBinsCoded ) 1103 { 1104 TComSlice *const pcSlice = pcPic->getSlice(getSliceIdx()); 1105 1106 const UInt startCtuTsAddr = pcSlice->getSliceSegmentCurStartCtuTsAddr(); 1107 const UInt boundingCtuTsAddr = pcSlice->getSliceSegmentCurEndCtuTsAddr(); 1108 1109 const UInt frameWidthInCtus = pcPic->getPicSym()->getFrameWidthInCtus(); 1110 const Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag(); 1111 const Bool wavefrontsEnabled = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag(); 1112 1113 // initialise entropy coder for the slice 1114 m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC ); 1115 m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder ); 1116 m_pcEntropyCoder->resetEntropy ( pcSlice ); 1117 1118 numBinsCoded = 0; 1119 m_pcBinCABAC->setBinCountingEnableFlag( true ); 1120 m_pcBinCABAC->setBinsCoded(0); 1121 1286 1122 #if ENC_DEC_TRACE 1287 1123 g_bJustDoIt = g_bEncDecTraceEnable; 1288 1124 #endif 1125 #if H_MV_ENC_DEC_TRAC 1126 #if ENC_DEC_TRACE 1127 incSymbolCounter(); 1128 #endif 1129 DTRACE_CABAC_VL( g_nSymbolCounter ); 1130 #else 1289 1131 DTRACE_CABAC_VL( g_nSymbolCounter++ ); 1132 #endif 1290 1133 DTRACE_CABAC_T( "\tPOC: " ); 1291 DTRACE_CABAC_V( rpcPic->getPOC() );1134 DTRACE_CABAC_V( pcPic->getPOC() ); 1292 1135 #if H_MV_ENC_DEC_TRAC 1293 1136 DTRACE_CABAC_T( " Layer: " ); 1294 DTRACE_CABAC_V( rpcPic->getLayerId() );1137 DTRACE_CABAC_V( pcPic->getLayerId() ); 1295 1138 #endif 1296 1139 DTRACE_CABAC_T( "\n" ); … … 1299 1142 #endif 1300 1143 1301 TEncTop* pcEncTop = (TEncTop*) m_pcCfg; 1302 TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream1303 Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();1304 UInt uiBitsOriginallyInSubstreams = 0;1305 {1306 UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;1307 for (UInt ui = 0; ui < uiTilesAcross; ui++)1308 {1309 m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state 1310 }1311 1312 for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)1313 {1314 uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();1315 }1316 1317 for (UInt ui = 0; ui < uiTilesAcross; ui++)1318 { 1319 m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder); //init. state1320 } 1321 }1322 1323 UInt uiWidthInLCUs = rpcPic->getPicSym()->getFrameWidthInCU();1324 UInt uiCol=0, uiLin=0, uiSubStrm=0;1325 UInt uiTileCol = 0;1326 UInt uiTileStartLCU = 0;1327 UInt uiTileLCUX = 0;1328 Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();1329 uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually1330 an encoding order index, so we need to convert the index (uiStartCUAddr)1331 into the real raster scan address (uiCUAddr) via the CUOrderMap */1332 uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr(); 1333 if( depSliceSegmentsEnabled )1334 { 1335 if( pcSlice->isNextSlice()||1336 uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())1337 { 1338 if (m_pcCfg->getWaveFrontsynchro())1339 { 1340 CTXMem[1]->loadContexts(m_pcSbacCoder);1341 } 1342 CTXMem[0]->loadContexts(m_pcSbacCoder);1343 }1344 else1345 {1346 if (m_pcCfg->getWaveFrontsynchro())1347 { 1348 uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);1349 m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );1350 Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();1351 uiLin = uiCUAddr / uiWidthInLCUs;1352 uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile1353 + uiLin%iNumSubstreamsPerTile;1354 if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs)1144 1145 if (depSliceSegmentsEnabled) 1146 { 1147 // modify initial contexts with previous slice segment if this is a dependent slice. 1148 const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr ); 1149 const UInt currentTileIdx=pcPic->getPicSym()->getTileIdxMap(ctuRsAddr); 1150 const TComTile *pCurrentTile=pcPic->getPicSym()->getTComTile(currentTileIdx); 1151 const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr(); 1152 1153 if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile ) 1154 { 1155 if( pCurrentTile->getTileWidthInCtus() >= 2 || !wavefrontsEnabled ) 1156 { 1157 m_pcSbacCoder->loadContexts(&m_lastSliceSegmentEndContextState); 1158 } 1159 } 1160 } 1161 1162 // for every CTU in the slice segment... 1163 1164 for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr ) 1165 { 1166 const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr); 1167 const TComTile ¤tTile = *(pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr))); 1168 const UInt firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr(); 1169 const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus; 1170 const UInt tileYPosInCtus = firstCtuRsAddrOfTile / frameWidthInCtus; 1171 const UInt ctuXPosInCtus = ctuRsAddr % frameWidthInCtus; 1172 const UInt ctuYPosInCtus = ctuRsAddr / frameWidthInCtus; 1173 const UInt uiSubStrm=pcPic->getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice); 1174 TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr ); 1175 1176 m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] ); 1177 1178 // set up CABAC contexts' state for this CTU 1179 if (ctuRsAddr == firstCtuRsAddrOfTile) 1180 { 1181 if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset 1182 { 1183 m_pcEntropyCoder->resetEntropy(pcSlice); 1184 } 1185 } 1186 else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled) 1187 { 1188 // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line. 1189 if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset 1190 { 1191 m_pcEntropyCoder->resetEntropy(pcSlice); 1192 } 1193 TComDataCU *pCtuUp = pCtu->getCtuAbove(); 1194 if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus) ) 1195 { 1196 TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 ); 1197 if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) ) 1355 1198 { 1356 uiCol = uiCUAddr % uiWidthInLCUs; 1357 uiTileLCUX = uiTileStartLCU % uiWidthInLCUs; 1358 if(uiCol==uiTileLCUX) 1359 { 1360 CTXMem[0]->loadContexts(m_pcSbacCoder); 1361 } 1199 // Top-right is available, so use it. 1200 m_pcSbacCoder->loadContexts( &m_entropyCodingSyncContextState ); 1362 1201 } 1363 1202 } 1364 pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] ); 1365 } 1366 } 1367 1368 UInt uiEncCUOrder; 1369 for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU(); 1370 uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU(); 1371 uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) ) 1372 { 1373 uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in? 1374 uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr(); 1375 uiTileLCUX = uiTileStartLCU % uiWidthInLCUs; 1376 //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr(); 1377 uiCol = uiCUAddr % uiWidthInLCUs; 1378 uiLin = uiCUAddr / uiWidthInLCUs; 1379 if (pcSlice->getPPS()->getNumSubstreams() > 1) 1380 { 1381 // independent tiles => substreams are "per tile". iNumSubstreams has already been multiplied. 1382 Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles(); 1383 uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile 1384 + uiLin%iNumSubstreamsPerTile; 1385 } 1386 else 1387 { 1388 // dependent tiles => substreams are "per frame". 1389 uiSubStrm = uiLin % iNumSubstreams; 1390 } 1391 1392 m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] ); 1393 // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line. 1394 if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro()) 1395 { 1396 // We'll sync if the TR is available. 1397 TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove(); 1398 UInt uiWidthInCU = rpcPic->getFrameWidthInCU(); 1399 UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1); 1400 TComDataCU *pcCUTR = NULL; 1401 if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU) ) 1203 } 1204 1205 #if NH_3D_QTLPC 1206 pcPic->setReduceBitsFlag(true); 1207 #endif 1208 if ( pcSlice->getSPS()->getUseSAO() ) 1209 { 1210 Bool bIsSAOSliceEnabled = false; 1211 Bool sliceEnabled[MAX_NUM_COMPONENT]; 1212 for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++) 1213 { 1214 ComponentID compId=ComponentID(comp); 1215 sliceEnabled[compId] = pcSlice->getSaoEnabledFlag(toChannelType(compId)) && (comp < pcPic->getNumberValidComponents()); 1216 if (sliceEnabled[compId]) 1402 1217 { 1403 pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );1218 bIsSAOSliceEnabled=true; 1404 1219 } 1405 if ( (true/*bEnforceSliceRestriction*/ && 1406 ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 1407 (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) || 1408 ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))) 1409 )) 1410 ) 1411 { 1412 // TR not available. 1413 } 1414 else 1415 { 1416 // TR is available, we use it. 1417 pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] ); 1418 } 1419 } 1420 m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]); //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder) 1421 1422 // reset the entropy coder 1423 if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() && // must be first CU of tile 1424 uiCUAddr!=0 && // cannot be first CU of picture 1425 uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() && 1426 uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU()) // cannot be first CU of slice 1427 { 1428 { 1429 // We're crossing into another tile, tiles are independent. 1430 // When tiles are independent, we have "substreams per tile". Each substream has already been terminated, and we no longer 1431 // have to perform it here. 1432 if (pcSlice->getPPS()->getNumSubstreams() > 1) 1433 { 1434 ; // do nothing. 1435 } 1436 else 1437 { 1438 SliceType sliceType = pcSlice->getSliceType(); 1439 if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE) 1440 { 1441 sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx(); 1442 } 1443 m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() ); 1444 // Byte-alignment in slice_data() when new tile 1445 pcSubstreams[uiSubStrm].writeByteAlignment(); 1446 } 1447 } 1448 { 1449 UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations(); 1450 UInt uiAccumulatedSubstreamLength = 0; 1451 for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++) 1452 { 1453 uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits(); 1454 } 1455 // add bits coded in previous dependent slices + bits coded so far 1456 // add number of emulation prevention byte count in the tile 1457 pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations ); 1458 } 1459 } 1460 1461 #if H_3D_QTLPC 1462 rpcPic->setReduceBitsFlag(true); 1463 #endif 1464 TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr ); 1465 if ( pcSlice->getSPS()->getUseSAO() ) 1466 { 1467 if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) 1468 { 1469 SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[uiCUAddr]; 1470 Bool sliceEnabled[NUM_SAO_COMPONENTS]; 1471 sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag(); 1472 sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma(); 1220 } 1221 if (bIsSAOSliceEnabled) 1222 { 1223 SAOBlkParam& saoblkParam = (pcPic->getPicSym()->getSAOBlkParam())[ctuRsAddr]; 1473 1224 1474 1225 Bool leftMergeAvail = false; 1475 1226 Bool aboveMergeAvail= false; 1476 1227 //merge left condition 1477 Int rx = ( uiCUAddr % uiWidthInLCUs);1228 Int rx = (ctuRsAddr % frameWidthInCtus); 1478 1229 if(rx > 0) 1479 1230 { 1480 leftMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-1);1231 leftMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-1); 1481 1232 } 1482 1233 1483 1234 //merge up condition 1484 Int ry = ( uiCUAddr / uiWidthInLCUs);1235 Int ry = (ctuRsAddr / frameWidthInCtus); 1485 1236 if(ry > 0) 1486 {1487 aboveMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-uiWidthInLCUs);1237 { 1238 aboveMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-frameWidthInCtus); 1488 1239 } 1489 1240 1490 m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam,sliceEnabled, leftMergeAvail, aboveMergeAvail); 1491 } 1492 } 1241 m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, pcPic->getPicSym()->getSPS().getBitDepths(), sliceEnabled, leftMergeAvail, aboveMergeAvail); 1242 } 1243 } 1244 1493 1245 #if ENC_DEC_TRACE 1494 1246 g_bJustDoIt = g_bEncDecTraceEnable; 1495 1247 #endif 1496 if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) && 1497 uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) ) 1498 { 1499 m_pcCuEncoder->encodeCU( pcCU ); 1500 } 1501 else 1502 { 1503 m_pcCuEncoder->encodeCU( pcCU ); 1504 } 1248 m_pcCuEncoder->encodeCtu( pCtu ); 1505 1249 #if ENC_DEC_TRACE 1506 1250 g_bJustDoIt = g_bEncDecTraceDisable; 1507 #endif 1508 pcSbacCoders[uiSubStrm].load(m_pcSbacCoder); //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder 1509 1510 1511 //Store probabilties of second LCU in line into buffer 1512 if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro()) 1513 { 1514 m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] ); 1515 } 1516 #if H_3D_QTLPC 1517 rpcPic->setReduceBitsFlag(false); 1518 #endif 1519 } 1251 #endif 1252 1253 //Store probabilities of second CTU in line into buffer 1254 if ( ctuXPosInCtus == tileXPosInCtus+1 && wavefrontsEnabled) 1255 { 1256 m_entropyCodingSyncContextState.loadContexts( m_pcSbacCoder ); 1257 } 1258 1259 // terminate the sub-stream, if required (end of slice-segment, end of tile, end of wavefront-CTU-row): 1260 if (ctuTsAddr+1 == boundingCtuTsAddr || 1261 ( ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus() && 1262 ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled) 1263 ) 1264 ) 1265 { 1266 m_pcEntropyCoder->encodeTerminatingBit(1); 1267 m_pcEntropyCoder->encodeSliceFinish(); 1268 // Byte-alignment in slice_data() when new tile 1269 pcSubstreams[uiSubStrm].writeByteAlignment(); 1270 1271 // write sub-stream size 1272 if (ctuTsAddr+1 != boundingCtuTsAddr) 1273 { 1274 pcSlice->addSubstreamSize( (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations() ); 1275 } 1276 } 1277 #if NH_3D_QTLPC 1278 pcPic->setReduceBitsFlag(false); 1279 #endif 1280 } // CTU-loop 1281 1520 1282 if( depSliceSegmentsEnabled ) 1521 1283 { 1522 if (m_pcCfg->getWaveFrontsynchro()) 1523 { 1524 CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU 1525 } 1526 CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice 1527 } 1284 m_lastSliceSegmentEndContextState.loadContexts( m_pcSbacCoder );//ctx end of dep.slice 1285 } 1286 1528 1287 #if ADAPTIVE_QP_SELECTION 1529 1288 if( m_pcCfg->getUseAdaptQpSelect() ) 1530 1289 { 1531 m_pcTrQuant->storeSliceQpNext(pcSlice); 1532 } 1533 #endif 1534 if (pcSlice->getPPS()->getCabacInitPresentFlag()) 1535 { 1536 if (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag()) 1537 { 1538 pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() ); 1539 } 1540 else 1541 { 1542 m_pcEntropyCoder->determineCabacInitIdx(); 1543 } 1544 } 1545 } 1546 1547 /** Determines the starting and bounding LCU address of current slice / dependent slice 1548 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true] 1549 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address 1550 */ 1551 Void TEncSlice::xDetermineStartAndBoundingCUAddr ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice ) 1552 { 1553 TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx()); 1554 UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice; 1555 UInt tileIdxIncrement; 1556 UInt tileIdx; 1557 UInt tileWidthInLcu; 1558 UInt tileHeightInLcu; 1559 UInt tileTotalCount; 1560 1561 uiStartCUAddrSlice = pcSlice->getSliceCurStartCUAddr(); 1562 UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame(); 1563 uiBoundingCUAddrSlice = uiNumberOfCUsInFrame; 1564 if (bEncodeSlice) 1565 { 1566 UInt uiCUAddrIncrement; 1567 switch (m_pcCfg->getSliceMode()) 1568 { 1569 case FIXED_NUMBER_OF_LCU: 1570 uiCUAddrIncrement = m_pcCfg->getSliceArgument(); 1571 uiBoundingCUAddrSlice = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1290 m_pcTrQuant->storeSliceQpNext(pcSlice); // TODO: this will only be storing the adaptive QP state of the very last slice-segment that is not dependent in the frame... Perhaps this should be moved to the compress slice loop. 1291 } 1292 #endif 1293 1294 if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag()) 1295 { 1296 m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx(pcSlice); 1297 } 1298 else 1299 { 1300 m_encCABACTableIdx = pcSlice->getSliceType(); 1301 } 1302 1303 numBinsCoded = m_pcBinCABAC->getBinsCoded(); 1304 } 1305 1306 Void TEncSlice::calculateBoundingCtuTsAddrForSlice(UInt &startCtuTSAddrSlice, UInt &boundingCtuTSAddrSlice, Bool &haveReachedTileBoundary, 1307 TComPic* pcPic, const Int sliceMode, const Int sliceArgument) 1308 { 1309 TComSlice* pcSlice = pcPic->getSlice(getSliceIdx()); 1310 const UInt numberOfCtusInFrame = pcPic->getNumberOfCtusInFrame(); 1311 const TComPPS &pps=*(pcSlice->getPPS()); 1312 boundingCtuTSAddrSlice=0; 1313 haveReachedTileBoundary=false; 1314 1315 switch (sliceMode) 1316 { 1317 case FIXED_NUMBER_OF_CTU: 1318 { 1319 UInt ctuAddrIncrement = sliceArgument; 1320 boundingCtuTSAddrSlice = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame; 1321 } 1572 1322 break; 1573 1323 case FIXED_NUMBER_OF_BYTES: 1574 uiCUAddrIncrement = rpcPic->getNumCUsInFrame(); 1575 uiBoundingCUAddrSlice = pcSlice->getSliceCurEndCUAddr(); 1324 boundingCtuTSAddrSlice = numberOfCtusInFrame; // This will be adjusted later if required. 1576 1325 break; 1577 1326 case FIXED_NUMBER_OF_TILES: 1578 tileIdx = rpcPic->getPicSym()->getTileIdxMap( 1579 rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU()) 1580 ); 1581 uiCUAddrIncrement = 0; 1582 tileTotalCount = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1); 1583 1584 for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++) 1585 { 1586 if((tileIdx + tileIdxIncrement) < tileTotalCount) 1327 { 1328 const UInt tileIdx = pcPic->getPicSym()->getTileIdxMap( pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice) ); 1329 const UInt tileTotalCount = (pcPic->getPicSym()->getNumTileColumnsMinus1()+1) * (pcPic->getPicSym()->getNumTileRowsMinus1()+1); 1330 UInt ctuAddrIncrement = 0; 1331 1332 for(UInt tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++) 1587 1333 { 1588 tileWidthInLcu = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth(); 1589 tileHeightInLcu = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight(); 1590 uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()); 1334 if((tileIdx + tileIdxIncrement) < tileTotalCount) 1335 { 1336 UInt tileWidthInCtus = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidthInCtus(); 1337 UInt tileHeightInCtus = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeightInCtus(); 1338 ctuAddrIncrement += (tileWidthInCtus * tileHeightInCtus); 1339 } 1591 1340 } 1592 } 1593 1594 uiBoundingCUAddrSlice = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();1341 1342 boundingCtuTSAddrSlice = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame; 1343 } 1595 1344 break; 1596 1345 default: 1597 uiCUAddrIncrement = rpcPic->getNumCUsInFrame(); 1598 uiBoundingCUAddrSlice = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1346 boundingCtuTSAddrSlice = numberOfCtusInFrame; 1599 1347 break; 1600 } 1348 } 1349 1350 // Adjust for tiles and wavefronts. 1351 const Bool wavefrontsAreEnabled = pps.getEntropyCodingSyncEnabledFlag(); 1352 1353 if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) && 1354 (pps.getNumTileRowsMinus1() > 0 || pps.getNumTileColumnsMinus1() > 0)) 1355 { 1356 const UInt ctuRSAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice); 1357 const UInt startTileIdx = pcPic->getPicSym()->getTileIdxMap(ctuRSAddr); 1358 1359 const TComTile *pStartingTile = pcPic->getPicSym()->getTComTile(startTileIdx); 1360 const UInt tileStartTsAddr = pcPic->getPicSym()->getCtuRsToTsAddrMap(pStartingTile->getFirstCtuRsAddr()); 1361 const UInt tileStartWidth = pStartingTile->getTileWidthInCtus(); 1362 const UInt tileStartHeight = pStartingTile->getTileHeightInCtus(); 1363 const UInt tileLastTsAddr_excl = tileStartTsAddr + tileStartWidth*tileStartHeight; 1364 const UInt tileBoundingCtuTsAddrSlice = tileLastTsAddr_excl; 1365 1366 const UInt ctuColumnOfStartingTile = ((startCtuTSAddrSlice-tileStartTsAddr)%tileStartWidth); 1367 if (wavefrontsAreEnabled && ctuColumnOfStartingTile!=0) 1368 { 1369 // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row 1370 const UInt numberOfCTUsToEndOfRow = tileStartWidth - ctuColumnOfStartingTile; 1371 const UInt wavefrontTileBoundingCtuAddrSlice = startCtuTSAddrSlice + numberOfCTUsToEndOfRow; 1372 if (wavefrontTileBoundingCtuAddrSlice < boundingCtuTSAddrSlice) 1373 { 1374 boundingCtuTSAddrSlice = wavefrontTileBoundingCtuAddrSlice; 1375 } 1376 } 1377 1378 if (tileBoundingCtuTsAddrSlice < boundingCtuTSAddrSlice) 1379 { 1380 boundingCtuTSAddrSlice = tileBoundingCtuTsAddrSlice; 1381 haveReachedTileBoundary = true; 1382 } 1383 } 1384 else if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) && wavefrontsAreEnabled && ((startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) != 0)) 1385 { 1386 // Adjust for wavefronts (no tiles). 1601 1387 // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row 1602 if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0)) 1603 { 1604 uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())); 1605 } 1606 pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice ); 1607 } 1608 else 1609 { 1610 UInt uiCUAddrIncrement ; 1611 switch (m_pcCfg->getSliceMode()) 1612 { 1613 case FIXED_NUMBER_OF_LCU: 1614 uiCUAddrIncrement = m_pcCfg->getSliceArgument(); 1615 uiBoundingCUAddrSlice = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1616 break; 1617 case FIXED_NUMBER_OF_TILES: 1618 tileIdx = rpcPic->getPicSym()->getTileIdxMap( 1619 rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU()) 1620 ); 1621 uiCUAddrIncrement = 0; 1622 tileTotalCount = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1); 1623 1624 for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++) 1625 { 1626 if((tileIdx + tileIdxIncrement) < tileTotalCount) 1627 { 1628 tileWidthInLcu = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth(); 1629 tileHeightInLcu = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight(); 1630 uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()); 1631 } 1632 } 1633 1634 uiBoundingCUAddrSlice = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1635 break; 1636 default: 1637 uiCUAddrIncrement = rpcPic->getNumCUsInFrame(); 1638 uiBoundingCUAddrSlice = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1639 break; 1640 } 1641 // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row 1642 if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0)) 1643 { 1644 uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())); 1645 } 1646 pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice ); 1647 } 1648 1649 Bool tileBoundary = false; 1650 if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 1651 (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0)) 1652 { 1653 UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU(); 1654 UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr); 1655 UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr); 1656 UInt tileBoundingCUAddrSlice = 0; 1657 while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx) 1658 { 1659 lcuEncAddr++; 1660 lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr); 1661 } 1662 tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU(); 1663 1664 if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice) 1665 { 1666 uiBoundingCUAddrSlice = tileBoundingCUAddrSlice; 1667 pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice ); 1668 tileBoundary = true; 1669 } 1670 } 1388 boundingCtuTSAddrSlice = min(boundingCtuTSAddrSlice, startCtuTSAddrSlice - (startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) + (pcPic->getFrameWidthInCtus())); 1389 } 1390 } 1391 1392 /** Determines the starting and bounding CTU address of current slice / dependent slice 1393 * \param [out] startCtuTsAddr 1394 * \param [out] boundingCtuTsAddr 1395 * \param [in] pcPic 1396 1397 * Updates startCtuTsAddr, boundingCtuTsAddr with appropriate CTU address 1398 */ 1399 Void TEncSlice::xDetermineStartAndBoundingCtuTsAddr ( UInt& startCtuTsAddr, UInt& boundingCtuTsAddr, TComPic* pcPic ) 1400 { 1401 TComSlice* pcSlice = pcPic->getSlice(getSliceIdx()); 1402 1403 // Non-dependent slice 1404 UInt startCtuTsAddrSlice = pcSlice->getSliceCurStartCtuTsAddr(); 1405 Bool haveReachedTileBoundarySlice = false; 1406 UInt boundingCtuTsAddrSlice; 1407 calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSlice, boundingCtuTsAddrSlice, haveReachedTileBoundarySlice, pcPic, 1408 m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument()); 1409 pcSlice->setSliceCurEndCtuTsAddr( boundingCtuTsAddrSlice ); 1410 pcSlice->setSliceCurStartCtuTsAddr( startCtuTsAddrSlice ); 1671 1411 1672 1412 // Dependent slice 1673 UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment; 1674 startCUAddrSliceSegment = pcSlice->getSliceSegmentCurStartCUAddr(); 1675 boundingCUAddrSliceSegment = uiNumberOfCUsInFrame; 1676 if (bEncodeSlice) 1677 { 1678 UInt uiCUAddrIncrement; 1679 switch (m_pcCfg->getSliceSegmentMode()) 1680 { 1681 case FIXED_NUMBER_OF_LCU: 1682 uiCUAddrIncrement = m_pcCfg->getSliceSegmentArgument(); 1683 boundingCUAddrSliceSegment = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1684 break; 1685 case FIXED_NUMBER_OF_BYTES: 1686 uiCUAddrIncrement = rpcPic->getNumCUsInFrame(); 1687 boundingCUAddrSliceSegment = pcSlice->getSliceSegmentCurEndCUAddr(); 1688 break; 1689 case FIXED_NUMBER_OF_TILES: 1690 tileIdx = rpcPic->getPicSym()->getTileIdxMap( 1691 rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU()) 1692 ); 1693 uiCUAddrIncrement = 0; 1694 tileTotalCount = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1); 1695 1696 for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++) 1697 { 1698 if((tileIdx + tileIdxIncrement) < tileTotalCount) 1699 { 1700 tileWidthInLcu = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth(); 1701 tileHeightInLcu = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight(); 1702 uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()); 1703 } 1704 } 1705 boundingCUAddrSliceSegment = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1706 break; 1707 default: 1708 uiCUAddrIncrement = rpcPic->getNumCUsInFrame(); 1709 boundingCUAddrSliceSegment = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1710 break; 1711 } 1712 // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row 1713 if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0)) 1714 { 1715 boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())); 1716 } 1717 pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment ); 1718 } 1719 else 1720 { 1721 UInt uiCUAddrIncrement; 1722 switch (m_pcCfg->getSliceSegmentMode()) 1723 { 1724 case FIXED_NUMBER_OF_LCU: 1725 uiCUAddrIncrement = m_pcCfg->getSliceSegmentArgument(); 1726 boundingCUAddrSliceSegment = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1727 break; 1728 case FIXED_NUMBER_OF_TILES: 1729 tileIdx = rpcPic->getPicSym()->getTileIdxMap( 1730 rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU()) 1731 ); 1732 uiCUAddrIncrement = 0; 1733 tileTotalCount = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1); 1734 1735 for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++) 1736 { 1737 if((tileIdx + tileIdxIncrement) < tileTotalCount) 1738 { 1739 tileWidthInLcu = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth(); 1740 tileHeightInLcu = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight(); 1741 uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()); 1742 } 1743 } 1744 boundingCUAddrSliceSegment = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1745 break; 1746 default: 1747 uiCUAddrIncrement = rpcPic->getNumCUsInFrame(); 1748 boundingCUAddrSliceSegment = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU(); 1749 break; 1750 } 1751 // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row 1752 if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0)) 1753 { 1754 boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())); 1755 } 1756 pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment ); 1757 } 1758 if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 1759 (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0)) 1760 { 1761 UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU(); 1762 UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr); 1763 UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr); 1764 UInt tileBoundingCUAddrSlice = 0; 1765 while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx) 1766 { 1767 lcuEncAddr++; 1768 lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr); 1769 } 1770 tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU(); 1771 1772 if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment) 1773 { 1774 boundingCUAddrSliceSegment = tileBoundingCUAddrSlice; 1775 pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment ); 1776 tileBoundary = true; 1777 } 1778 } 1779 1780 if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice) 1781 { 1782 boundingCUAddrSliceSegment = uiBoundingCUAddrSlice; 1783 pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice); 1784 } 1785 1786 //calculate real dependent slice start address 1787 UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU(); 1788 UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU(); 1789 UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; 1790 UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; 1791 UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples(); 1792 UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples(); 1793 while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight)) 1794 { 1795 uiInternalAddress++; 1796 if(uiInternalAddress>=rpcPic->getNumPartInCU()) 1797 { 1798 uiInternalAddress=0; 1799 uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1); 1800 } 1801 uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; 1802 uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; 1803 } 1804 UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress); 1805 1806 pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress); 1807 startCUAddrSliceSegment=uiRealStartAddress; 1808 1809 //calculate real slice start address 1810 uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU(); 1811 uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU(); 1812 uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; 1813 uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; 1814 uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples(); 1815 uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples(); 1816 while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight)) 1817 { 1818 uiInternalAddress++; 1819 if(uiInternalAddress>=rpcPic->getNumPartInCU()) 1820 { 1821 uiInternalAddress=0; 1822 uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1); 1823 } 1824 uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; 1825 uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; 1826 } 1827 uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress); 1828 1829 pcSlice->setSliceCurStartCUAddr(uiRealStartAddress); 1830 uiStartCUAddrSlice=uiRealStartAddress; 1831 1413 UInt startCtuTsAddrSliceSegment = pcSlice->getSliceSegmentCurStartCtuTsAddr(); 1414 Bool haveReachedTileBoundarySliceSegment = false; 1415 UInt boundingCtuTsAddrSliceSegment; 1416 calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSliceSegment, boundingCtuTsAddrSliceSegment, haveReachedTileBoundarySliceSegment, pcPic, 1417 m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument()); 1418 if (boundingCtuTsAddrSliceSegment>boundingCtuTsAddrSlice) 1419 { 1420 boundingCtuTsAddrSliceSegment = boundingCtuTsAddrSlice; 1421 } 1422 pcSlice->setSliceSegmentCurEndCtuTsAddr( boundingCtuTsAddrSliceSegment ); 1423 pcSlice->setSliceSegmentCurStartCtuTsAddr(startCtuTsAddrSliceSegment); 1424 1832 1425 // Make a joint decision based on reconstruction and dependent slice bounds 1833 startCUAddr = max(uiStartCUAddrSlice , startCUAddrSliceSegment ); 1834 boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment); 1835 1836 1837 if (!bEncodeSlice) 1838 { 1839 // For fixed number of LCU within an entropy and reconstruction slice we already know whether we will encounter end of entropy and/or reconstruction slice 1840 // first. Set the flags accordingly. 1841 if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU) 1842 || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU) 1843 || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 1844 || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU) 1845 || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 1846 || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0) 1847 || tileBoundary 1848 ) 1849 { 1850 if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment) 1851 { 1852 pcSlice->setNextSlice ( true ); 1853 pcSlice->setNextSliceSegment( false ); 1854 } 1855 else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment) 1856 { 1857 pcSlice->setNextSlice ( false ); 1858 pcSlice->setNextSliceSegment( true ); 1859 } 1860 else 1861 { 1862 pcSlice->setNextSlice ( true ); 1863 pcSlice->setNextSliceSegment( true ); 1864 } 1865 } 1866 else 1867 { 1868 pcSlice->setNextSlice ( false ); 1869 pcSlice->setNextSliceSegment( false ); 1870 } 1871 } 1426 startCtuTsAddr = max(startCtuTsAddrSlice , startCtuTsAddrSliceSegment ); 1427 boundingCtuTsAddr = boundingCtuTsAddrSliceSegment; 1872 1428 } 1873 1429
Note: See TracChangeset for help on using the changeset viewer.