Changeset 56 in 3DVCSoftware for trunk/source/Lib/TLibDecoder/TDecSlice.cpp
- Timestamp:
- 11 May 2012, 21:20:17 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/Lib/TLibDecoder/TDecSlice.cpp
r5 r56 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-201 1,ISO/IEC6 * Copyright (c) 2010-2012, ITU/ISO/IEC 7 7 * All rights reserved. 8 8 * … … 15 15 * this list of conditions and the following disclaimer in the documentation 16 16 * and/or other materials provided with the distribution. 17 * * Neither the name of the I SO/IEC nor the names of its contributors may17 * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may 18 18 * be used to endorse or promote products derived from this software without 19 19 * specific prior written permission. … … 32 32 */ 33 33 34 35 36 34 /** \file TDecSlice.cpp 37 35 \brief slice decoder class … … 40 38 #include "TDecSlice.h" 41 39 40 //! \ingroup TLibDecoder 41 //! \{ 42 42 43 ////////////////////////////////////////////////////////////////////// 43 44 // Construction/Destruction … … 46 47 TDecSlice::TDecSlice() 47 48 { 49 m_pcBufferSbacDecoders = NULL; 50 m_pcBufferBinCABACs = NULL; 51 m_pcBufferLowLatSbacDecoders = NULL; 52 m_pcBufferLowLatBinCABACs = NULL; 48 53 } 49 54 … … 58 63 Void TDecSlice::destroy() 59 64 { 65 if ( m_pcBufferSbacDecoders ) 66 { 67 delete[] m_pcBufferSbacDecoders; 68 m_pcBufferSbacDecoders = NULL; 69 } 70 if ( m_pcBufferBinCABACs ) 71 { 72 delete[] m_pcBufferBinCABACs; 73 m_pcBufferBinCABACs = NULL; 74 } 75 if ( m_pcBufferLowLatSbacDecoders ) 76 { 77 delete[] m_pcBufferLowLatSbacDecoders; 78 m_pcBufferLowLatSbacDecoders = NULL; 79 } 80 if ( m_pcBufferLowLatBinCABACs ) 81 { 82 delete[] m_pcBufferLowLatBinCABACs; 83 m_pcBufferLowLatBinCABACs = NULL; 84 } 60 85 } 61 86 … … 66 91 } 67 92 68 Void TDecSlice::decompressSlice(TCom Bitstream* pcBitstream, TComPic*& rpcPic)93 Void TDecSlice::decompressSlice(TComInputBitstream* pcBitstream, TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders) 69 94 { 70 95 TComDataCU* pcCU; 71 96 UInt uiIsLast = 0; 72 Int iStartCUAddr = max(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr(), rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getEntropySliceCurStartCUAddr()); 97 Int iStartCUEncOrder = max(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU(), rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getEntropySliceCurStartCUAddr()/rpcPic->getNumPartInCU()); 98 Int iStartCUAddr = rpcPic->getPicSym()->getCUOrderMap(iStartCUEncOrder); 73 99 74 100 // decoder don't need prediction & residual frame buffer … … 79 105 g_bJustDoIt = g_bEncDecTraceEnable; 80 106 #endif 81 DTRACE_CABAC_V ( g_nSymbolCounter++ );107 DTRACE_CABAC_VL( g_nSymbolCounter++ ); 82 108 DTRACE_CABAC_T( "\tPOC: " ); 83 109 DTRACE_CABAC_V( rpcPic->getPOC() ); … … 88 114 #endif 89 115 90 // for all CUs in slice 91 UInt uiLastCUAddr = iStartCUAddr; 92 for( Int iCUAddr = iStartCUAddr; !uiIsLast && iCUAddr < rpcPic->getNumCUsInFrame(); iCUAddr++, uiLastCUAddr++ ) 116 UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1; 117 TComSlice* pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx()); 118 UInt iSymbolMode = pcSlice->getPPS()->getEntropyCodingMode(); 119 Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams(); 120 121 if( iSymbolMode ) 122 { 123 m_pcBufferSbacDecoders = new TDecSbac [uiTilesAcross]; 124 m_pcBufferBinCABACs = new TDecBinCABAC[uiTilesAcross]; 125 for (UInt ui = 0; ui < uiTilesAcross; ui++) 126 { 127 m_pcBufferSbacDecoders[ui].init(&m_pcBufferBinCABACs[ui]); 128 } 129 //save init. state 130 for (UInt ui = 0; ui < uiTilesAcross; ui++) 131 { 132 m_pcBufferSbacDecoders[ui].load(pcSbacDecoder); 133 } 134 } 135 if( iSymbolMode ) 136 { 137 m_pcBufferLowLatSbacDecoders = new TDecSbac [uiTilesAcross]; 138 m_pcBufferLowLatBinCABACs = new TDecBinCABAC[uiTilesAcross]; 139 for (UInt ui = 0; ui < uiTilesAcross; ui++) 140 m_pcBufferLowLatSbacDecoders[ui].init(&m_pcBufferLowLatBinCABACs[ui]); 141 //save init. state 142 for (UInt ui = 0; ui < uiTilesAcross; ui++) 143 m_pcBufferLowLatSbacDecoders[ui].load(pcSbacDecoder); 144 } 145 146 UInt uiWidthInLCUs = rpcPic->getPicSym()->getFrameWidthInCU(); 147 //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU(); 148 UInt uiCol=0, uiLin=0, uiSubStrm=0; 149 150 #if !REMOVE_TILE_DEPENDENCE 151 Int iBreakDep; 152 #endif 153 UInt uiTileCol; 154 UInt uiTileStartLCU; 155 UInt uiTileLCUX; 156 UInt uiTileLCUY; 157 UInt uiTileWidth; 158 UInt uiTileHeight; 159 Int iNumSubstreamsPerTile = 1; // if independent. 160 161 for( Int iCUAddr = iStartCUAddr; !uiIsLast && iCUAddr < rpcPic->getNumCUsInFrame(); iCUAddr = rpcPic->getPicSym()->xCalculateNxtCUAddr(iCUAddr) ) 93 162 { 94 163 pcCU = rpcPic->getCU( iCUAddr ); 95 164 pcCU->initCU( rpcPic, iCUAddr ); 96 165 #if !REMOVE_TILE_DEPENDENCE 166 iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr(); 167 #endif 168 uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in? 169 uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr(); 170 uiTileLCUX = uiTileStartLCU % uiWidthInLCUs; 171 uiTileLCUY = uiTileStartLCU / uiWidthInLCUs; 172 uiTileWidth = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getTileWidth(); 173 uiTileHeight = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getTileHeight(); 174 uiCol = iCUAddr % uiWidthInLCUs; 175 uiLin = iCUAddr / uiWidthInLCUs; 176 // inherit from TR if necessary, select substream to use. 177 #if WPP_SIMPLIFICATION 178 if( iSymbolMode && pcSlice->getPPS()->getNumSubstreams() > 1 ) 179 #else 180 if( iSymbolMode && pcSlice->getPPS()->getEntropyCodingSynchro() ) 181 #endif 182 { 183 #if !REMOVE_TILE_DEPENDENCE 184 #if WPP_SIMPLIFICATION 185 if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1) 186 #else 187 if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro()) 188 #endif 189 #else 190 #if WPP_SIMPLIFICATION 191 if (pcSlice->getPPS()->getNumSubstreams() > 1) 192 #else 193 if (pcSlice->getPPS()->getEntropyCodingSynchro()) 194 #endif 195 #endif 196 { 197 // independent tiles => substreams are "per tile". iNumSubstreams has already been multiplied. 198 iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles(); 199 uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(iCUAddr)*iNumSubstreamsPerTile 200 + uiLin%iNumSubstreamsPerTile; 201 } 202 else 203 { 204 // dependent tiles => substreams are "per frame". 205 uiSubStrm = uiLin % iNumSubstreams; 206 } 207 m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] ); 208 // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line. 209 #if WPP_SIMPLIFICATION 210 if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX) 211 #else 212 if (pcSlice->getPPS()->getEntropyCodingSynchro() && uiCol == uiTileLCUX) 213 #endif 214 { 215 // We'll sync if the TR is available. 216 TComDataCU *pcCUUp = pcCU->getCUAbove(); 217 UInt uiWidthInCU = rpcPic->getFrameWidthInCU(); 218 TComDataCU *pcCUTR = NULL; 219 #if WPP_SIMPLIFICATION 220 if ( pcCUUp && ((iCUAddr%uiWidthInCU+1) < uiWidthInCU) ) 221 { 222 pcCUTR = rpcPic->getCU( iCUAddr - uiWidthInCU + 1 ); 223 } 224 #else 225 if ( pcCUUp && ((iCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU) ) 226 { 227 pcCUTR = rpcPic->getCU( iCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() ); 228 } 229 #endif 230 UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1); 231 232 if ( (true/*bEnforceSliceRestriction*/ && 233 ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 234 ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) || 235 #if !REMOVE_TILE_DEPENDENCE 236 (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))) 237 #else 238 ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))) 239 #endif 240 ))|| 241 (true/*bEnforceEntropySliceRestriction*/ && 242 ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 243 ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr()) || 244 #if !REMOVE_TILE_DEPENDENCE 245 (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))) 246 #else 247 ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))) 248 #endif 249 )) 250 ) 251 { 252 // TR not available. 253 } 254 else 255 { 256 // TR is available, we use it. 257 pcSbacDecoders[uiSubStrm].loadContexts( &m_pcBufferSbacDecoders[uiTileCol] ); 258 } 259 } 260 pcSbacDecoder->load(&pcSbacDecoders[uiSubStrm]); //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders) 261 } 262 #if WPP_SIMPLIFICATION 263 else if ( iSymbolMode && pcSlice->getPPS()->getNumSubstreams() <= 1 ) 264 #else 265 else if ( iSymbolMode && !pcSlice->getPPS()->getEntropyCodingSynchro() ) 266 #endif 267 { 268 // Set variables to appropriate values to avoid later code change. 269 iNumSubstreamsPerTile = 1; 270 } 271 272 if ( (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) && // 1st in tile. 273 (iCUAddr!=0) && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())) // !1st in frame && !1st in slice 274 { 275 #if WPP_SIMPLIFICATION 276 if (pcSlice->getPPS()->getNumSubstreams() > 1) 277 #else 278 if (pcSlice->getPPS()->getEntropyCodingSynchro()) 279 #endif 280 { 281 // We're crossing into another tile, tiles are independent. 282 // When tiles are independent, we have "substreams per tile". Each substream has already been terminated, and we no longer 283 // have to perform it here. 284 // For TILES_DECODER, there can be a header at the start of the 1st substream in a tile. These are read when the substreams 285 // are extracted, not here. 286 } 287 else 288 { 289 #if CABAC_INIT_FLAG 290 SliceType sliceType = pcSlice->getSliceType(); 291 if (pcSlice->getCabacInitFlag()) 292 { 293 switch (sliceType) 294 { 295 case P_SLICE: // change initialization table to B_SLICE intialization 296 sliceType = B_SLICE; 297 break; 298 case B_SLICE: // change initialization table to P_SLICE intialization 299 sliceType = P_SLICE; 300 break; 301 default : // should not occur 302 assert(0); 303 } 304 } 305 m_pcEntropyDecoder->updateContextTables( sliceType, pcSlice->getSliceQp() ); 306 #else 307 m_pcEntropyDecoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() ); 308 #endif 309 } 310 311 Bool bTileMarkerFoundFlag = false; 312 TComInputBitstream *pcTmpPtr; 313 pcTmpPtr = ppcSubstreams[uiSubStrm]; // for CABAC 314 315 for (UInt uiIdx=0; uiIdx<pcTmpPtr->getTileMarkerLocationCount(); uiIdx++) 316 { 317 if ( pcTmpPtr->getByteLocation() == (pcTmpPtr->getTileMarkerLocation( uiIdx )+2) ) 318 { 319 bTileMarkerFoundFlag = true; 320 break; 321 } 322 } 323 324 if (bTileMarkerFoundFlag) 325 { 326 UInt uiTileIdx; 327 // Read tile index 328 m_pcEntropyDecoder->readTileMarker( uiTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx() ); 329 } 330 } 331 332 #if !REMOVE_TILE_DEPENDENCE 333 if ( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) ) 334 { 335 // Synchronize cabac probabilities with LCU among Tiles 336 if( (uiTileLCUX != 0) && 337 (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) ) 338 { 339 TComDataCU *pcCULeft = pcCU->getCULeft(); 340 UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1); 341 342 if ( (true/*bEnforceSliceRestriction*/ && 343 ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 344 ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 345 ) 346 )|| 347 (true/*bEnforceEntropySliceRestriction*/ && 348 ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 349 ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr()) 350 ) 351 ) 352 ) 353 { 354 // Left not available. 355 } 356 else 357 { 358 // Left is available, we use it. 359 pcSbacDecoders[uiSubStrm].loadContexts( &m_pcBufferLowLatSbacDecoders[uiTileCol-1] ); 360 pcSbacDecoder->loadContexts(&pcSbacDecoders[uiSubStrm]); //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders) 361 } 362 } 363 } 364 #endif 365 366 97 367 #if ENC_DEC_TRACE 98 368 g_bJustDoIt = g_bEncDecTraceEnable; 99 369 #endif 370 #if SAO_UNIT_INTERLEAVING 371 if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() ) 372 { 373 pcSlice->getAPS()->getSaoParam()->bSaoFlag[0] = pcSlice->getSaoEnabledFlag(); 374 if (iCUAddr == iStartCUAddr) 375 { 376 pcSlice->getAPS()->getSaoParam()->bSaoFlag[1] = pcSlice->getSaoEnabledFlagCb(); 377 pcSlice->getAPS()->getSaoParam()->bSaoFlag[2] = pcSlice->getSaoEnabledFlagCr(); 378 } 379 Int numCuInWidth = pcSlice->getAPS()->getSaoParam()->numCuInWidth; 380 Int cuAddrInSlice = iCUAddr - pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU(); 381 Int cuAddrUpInSlice = cuAddrInSlice - numCuInWidth; 382 Int rx = iCUAddr % numCuInWidth; 383 Int ry = iCUAddr / numCuInWidth; 384 pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, cuAddrInSlice, cuAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag() ); 385 } 386 #endif 387 100 388 m_pcCuDecoder->decodeCU ( pcCU, uiIsLast ); 101 389 m_pcCuDecoder->decompressCU ( pcCU ); … … 104 392 g_bJustDoIt = g_bEncDecTraceDisable; 105 393 #endif 106 } 107 108 109 } 394 if( iSymbolMode ) 395 { 396 #if OL_FLUSH 397 /*If at the end of a LCU line but not at the end of a substream, perform CABAC flush*/ 398 #if WPP_SIMPLIFICATION 399 if (!uiIsLast && pcSlice->getPPS()->getNumSubstreams() > 1) 400 #else 401 if (!uiIsLast && pcSlice->getPPS()->getCabacIstateReset()) 402 #endif 403 { 404 #if !REMOVE_TILE_DEPENDENCE 405 if ((iBreakDep && (uiCol == uiTileLCUX+uiTileWidth-1) && (uiLin+iNumSubstreamsPerTile < uiTileLCUY+uiTileHeight)) 406 || (!iBreakDep && (uiCol == uiWidthInLCUs-1) && (uiLin+iNumSubstreams < pcCU->getPic()->getFrameHeightInCU()))) 407 #else 408 if ((uiCol == uiTileLCUX+uiTileWidth-1) && (uiLin+iNumSubstreamsPerTile < uiTileLCUY+uiTileHeight)) 409 #endif 410 { 411 m_pcEntropyDecoder->decodeFlush(); 412 } 413 } 414 #endif 415 pcSbacDecoders[uiSubStrm].load(pcSbacDecoder); 416 417 //Store probabilities of second LCU in line into buffer 418 #if WPP_SIMPLIFICATION 419 if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1)) 420 #else 421 if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro())) 422 #endif 423 { 424 m_pcBufferSbacDecoders[uiTileCol].loadContexts( &pcSbacDecoders[uiSubStrm] ); 425 } 426 427 } 428 #if !REMOVE_TILE_DEPENDENCE 429 if ( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) ) 430 { 431 pcSbacDecoders[uiSubStrm].load(pcSbacDecoder); 432 //Store probabilties for next tile 433 if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 434 (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getRightEdgePosInCU()) ) 435 { 436 m_pcBufferLowLatSbacDecoders[uiTileCol].loadContexts( &pcSbacDecoders[uiSubStrm] ); 437 } 438 } 439 #endif 440 } 441 442 } 443 444 ParameterSetManagerDecoder::ParameterSetManagerDecoder() 445 : m_spsBuffer(256) 446 , m_ppsBuffer(16) 447 , m_apsBuffer(64) 448 { 449 450 } 451 452 ParameterSetManagerDecoder::~ParameterSetManagerDecoder() 453 { 454 455 } 456 457 TComSPS* ParameterSetManagerDecoder::getPrefetchedSPS (Int spsId) 458 { 459 if (m_spsBuffer.getPS(spsId) != NULL ) 460 { 461 return m_spsBuffer.getPS(spsId); 462 } 463 else 464 { 465 return getSPS(spsId); 466 } 467 } 468 469 TComPPS* ParameterSetManagerDecoder::getPrefetchedPPS (Int ppsId) 470 { 471 if (m_ppsBuffer.getPS(ppsId) != NULL ) 472 { 473 return m_ppsBuffer.getPS(ppsId); 474 } 475 else 476 { 477 return getPPS(ppsId); 478 } 479 } 480 481 TComAPS* ParameterSetManagerDecoder::getPrefetchedAPS (Int apsId) 482 { 483 if (m_apsBuffer.getPS(apsId) != NULL ) 484 { 485 return m_apsBuffer.getPS(apsId); 486 } 487 else 488 { 489 return getAPS(apsId); 490 } 491 } 492 493 Void ParameterSetManagerDecoder::applyPrefetchedPS() 494 { 495 m_apsMap.mergePSList(m_apsBuffer); 496 m_ppsMap.mergePSList(m_ppsBuffer); 497 m_spsMap.mergePSList(m_spsBuffer); 498 } 499 500 //! \}
Note: See TracChangeset for help on using the changeset viewer.