[313] | 1 | /* The copyright in this software is being made available under the BSD |
---|
| 2 | * License, included below. This software may be subject to other third party |
---|
| 3 | * and contributor rights, including patent rights, and no such rights are |
---|
| 4 | * granted under this license. |
---|
| 5 | * |
---|
[595] | 6 | * Copyright (c) 2010-2014, ITU/ISO/IEC |
---|
[313] | 7 | * All rights reserved. |
---|
| 8 | * |
---|
| 9 | * Redistribution and use in source and binary forms, with or without |
---|
| 10 | * modification, are permitted provided that the following conditions are met: |
---|
| 11 | * |
---|
| 12 | * * Redistributions of source code must retain the above copyright notice, |
---|
| 13 | * this list of conditions and the following disclaimer. |
---|
| 14 | * * Redistributions in binary form must reproduce the above copyright notice, |
---|
| 15 | * this list of conditions and the following disclaimer in the documentation |
---|
| 16 | * and/or other materials provided with the distribution. |
---|
| 17 | * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may |
---|
| 18 | * be used to endorse or promote products derived from this software without |
---|
| 19 | * specific prior written permission. |
---|
| 20 | * |
---|
| 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
| 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS |
---|
| 25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
---|
| 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
---|
| 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
---|
| 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
---|
| 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
| 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
---|
| 31 | * THE POSSIBILITY OF SUCH DAMAGE. |
---|
| 32 | */ |
---|
| 33 | |
---|
| 34 | /** \file TEncGOP.cpp |
---|
| 35 | \brief GOP encoder class |
---|
| 36 | */ |
---|
| 37 | |
---|
| 38 | #include <list> |
---|
| 39 | #include <algorithm> |
---|
| 40 | #include <functional> |
---|
| 41 | |
---|
| 42 | #include "TEncTop.h" |
---|
| 43 | #include "TEncGOP.h" |
---|
| 44 | #include "TEncAnalyze.h" |
---|
| 45 | #include "libmd5/MD5.h" |
---|
| 46 | #include "TLibCommon/SEI.h" |
---|
| 47 | #include "TLibCommon/NAL.h" |
---|
| 48 | #include "NALwrite.h" |
---|
| 49 | #include <time.h> |
---|
| 50 | #include <math.h> |
---|
[906] | 51 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 52 | #include <limits.h> |
---|
| 53 | #endif |
---|
[313] | 54 | |
---|
| 55 | using namespace std; |
---|
| 56 | //! \ingroup TLibEncoder |
---|
| 57 | //! \{ |
---|
| 58 | |
---|
| 59 | // ==================================================================================================================== |
---|
| 60 | // Constructor / destructor / initialization / destroy |
---|
| 61 | // ==================================================================================================================== |
---|
| 62 | Int getLSB(Int poc, Int maxLSB) |
---|
| 63 | { |
---|
| 64 | if (poc >= 0) |
---|
| 65 | { |
---|
| 66 | return poc % maxLSB; |
---|
| 67 | } |
---|
| 68 | else |
---|
| 69 | { |
---|
| 70 | return (maxLSB - ((-poc) % maxLSB)) % maxLSB; |
---|
| 71 | } |
---|
| 72 | } |
---|
| 73 | |
---|
| 74 | TEncGOP::TEncGOP() |
---|
| 75 | { |
---|
| 76 | m_iLastIDR = 0; |
---|
| 77 | m_iGopSize = 0; |
---|
| 78 | m_iNumPicCoded = 0; //Niko |
---|
| 79 | m_bFirst = true; |
---|
[713] | 80 | #if ALLOW_RECOVERY_POINT_AS_RAP |
---|
| 81 | m_iLastRecoveryPicPOC = 0; |
---|
| 82 | #endif |
---|
[313] | 83 | |
---|
| 84 | m_pcCfg = NULL; |
---|
| 85 | m_pcSliceEncoder = NULL; |
---|
| 86 | m_pcListPic = NULL; |
---|
| 87 | |
---|
| 88 | m_pcEntropyCoder = NULL; |
---|
| 89 | m_pcCavlcCoder = NULL; |
---|
| 90 | m_pcSbacCoder = NULL; |
---|
| 91 | m_pcBinCABAC = NULL; |
---|
| 92 | |
---|
| 93 | m_bSeqFirst = true; |
---|
| 94 | |
---|
| 95 | m_bRefreshPending = 0; |
---|
| 96 | m_pocCRA = 0; |
---|
[815] | 97 | #if POC_RESET_IDC_ENCODER |
---|
| 98 | m_pocCraWithoutReset = 0; |
---|
| 99 | m_associatedIrapPocBeforeReset = 0; |
---|
| 100 | #endif |
---|
[313] | 101 | m_numLongTermRefPicSPS = 0; |
---|
| 102 | ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps)); |
---|
| 103 | ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag)); |
---|
| 104 | m_cpbRemovalDelay = 0; |
---|
| 105 | m_lastBPSEI = 0; |
---|
| 106 | xResetNonNestedSEIPresentFlags(); |
---|
| 107 | xResetNestedSEIPresentFlags(); |
---|
[595] | 108 | #if FIX1172 |
---|
| 109 | m_associatedIRAPType = NAL_UNIT_CODED_SLICE_IDR_N_LP; |
---|
| 110 | m_associatedIRAPPOC = 0; |
---|
| 111 | #endif |
---|
[815] | 112 | #if SVC_EXTENSION |
---|
[313] | 113 | m_pcPredSearch = NULL; |
---|
[713] | 114 | #if Q0048_CGS_3D_ASYMLUT |
---|
| 115 | m_temp = NULL; |
---|
| 116 | m_pColorMappedPic = NULL; |
---|
| 117 | #endif |
---|
[815] | 118 | #if POC_RESET_IDC_ENCODER |
---|
| 119 | m_lastPocPeriodId = -1; |
---|
| 120 | #endif |
---|
| 121 | #endif //SVC_EXTENSION |
---|
[313] | 122 | return; |
---|
| 123 | } |
---|
| 124 | |
---|
| 125 | TEncGOP::~TEncGOP() |
---|
| 126 | { |
---|
[713] | 127 | #if Q0048_CGS_3D_ASYMLUT |
---|
| 128 | if(m_pColorMappedPic) |
---|
| 129 | { |
---|
| 130 | m_pColorMappedPic->destroy(); |
---|
| 131 | delete m_pColorMappedPic; |
---|
| 132 | m_pColorMappedPic = NULL; |
---|
| 133 | } |
---|
| 134 | if(m_temp) |
---|
| 135 | { |
---|
| 136 | free_mem2DintWithPad(m_temp, m_iTap>>1, 0); |
---|
| 137 | m_temp = NULL; |
---|
| 138 | } |
---|
| 139 | #endif |
---|
[313] | 140 | } |
---|
| 141 | |
---|
| 142 | /** Create list to contain pointers to LCU start addresses of slice. |
---|
| 143 | */ |
---|
| 144 | #if SVC_EXTENSION |
---|
| 145 | Void TEncGOP::create( UInt layerId ) |
---|
| 146 | { |
---|
| 147 | m_bLongtermTestPictureHasBeenCoded = 0; |
---|
| 148 | m_bLongtermTestPictureHasBeenCoded2 = 0; |
---|
| 149 | m_layerId = layerId; |
---|
| 150 | } |
---|
| 151 | #else |
---|
| 152 | Void TEncGOP::create() |
---|
| 153 | { |
---|
| 154 | m_bLongtermTestPictureHasBeenCoded = 0; |
---|
| 155 | m_bLongtermTestPictureHasBeenCoded2 = 0; |
---|
| 156 | } |
---|
| 157 | #endif |
---|
| 158 | |
---|
| 159 | Void TEncGOP::destroy() |
---|
| 160 | { |
---|
| 161 | } |
---|
| 162 | |
---|
| 163 | Void TEncGOP::init ( TEncTop* pcTEncTop ) |
---|
| 164 | { |
---|
| 165 | m_pcEncTop = pcTEncTop; |
---|
| 166 | m_pcCfg = pcTEncTop; |
---|
| 167 | m_pcSliceEncoder = pcTEncTop->getSliceEncoder(); |
---|
| 168 | m_pcListPic = pcTEncTop->getListPic(); |
---|
| 169 | |
---|
| 170 | m_pcEntropyCoder = pcTEncTop->getEntropyCoder(); |
---|
| 171 | m_pcCavlcCoder = pcTEncTop->getCavlcCoder(); |
---|
| 172 | m_pcSbacCoder = pcTEncTop->getSbacCoder(); |
---|
| 173 | m_pcBinCABAC = pcTEncTop->getBinCABAC(); |
---|
| 174 | m_pcLoopFilter = pcTEncTop->getLoopFilter(); |
---|
| 175 | m_pcBitCounter = pcTEncTop->getBitCounter(); |
---|
| 176 | |
---|
| 177 | //--Adaptive Loop filter |
---|
| 178 | m_pcSAO = pcTEncTop->getSAO(); |
---|
| 179 | m_pcRateCtrl = pcTEncTop->getRateCtrl(); |
---|
| 180 | m_lastBPSEI = 0; |
---|
| 181 | m_totalCoded = 0; |
---|
| 182 | |
---|
| 183 | #if SVC_EXTENSION |
---|
| 184 | m_ppcTEncTop = pcTEncTop->getLayerEnc(); |
---|
| 185 | m_pcPredSearch = pcTEncTop->getPredSearch(); ///< encoder search class |
---|
[713] | 186 | #if Q0048_CGS_3D_ASYMLUT |
---|
| 187 | if( pcTEncTop->getLayerId() ) |
---|
| 188 | { |
---|
| 189 | m_Enc3DAsymLUTPicUpdate.create( m_pcCfg->getCGSMaxOctantDepth() , g_bitDepthYLayer[pcTEncTop->getLayerId()-1] , g_bitDepthCLayer[pcTEncTop->getLayerId()-1] , g_bitDepthYLayer[pcTEncTop->getLayerId()] , g_bitDepthCLayer[pcTEncTop->getLayerId()] , m_pcCfg->getCGSMaxYPartNumLog2() /*, m_pcCfg->getCGSPhaseAlignment()*/ ); |
---|
| 190 | m_Enc3DAsymLUTPPS.create( m_pcCfg->getCGSMaxOctantDepth() , g_bitDepthYLayer[pcTEncTop->getLayerId()-1] , g_bitDepthCLayer[pcTEncTop->getLayerId()-1] , g_bitDepthYLayer[pcTEncTop->getLayerId()] , g_bitDepthCLayer[pcTEncTop->getLayerId()] , m_pcCfg->getCGSMaxYPartNumLog2() /*, m_pcCfg->getCGSPhaseAlignment()*/ ); |
---|
| 191 | if(!m_pColorMappedPic) |
---|
| 192 | { |
---|
| 193 | m_pColorMappedPic = new TComPicYuv; |
---|
[815] | 194 | m_pColorMappedPic->create( m_ppcTEncTop[0]->getSourceWidth(), m_ppcTEncTop[0]->getSourceHeight(), m_ppcTEncTop[0]->getChromaFormatIDC(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, NULL ); |
---|
[713] | 195 | } |
---|
| 196 | } |
---|
| 197 | #endif |
---|
[815] | 198 | #endif //SVC_EXTENSION |
---|
[313] | 199 | } |
---|
| 200 | |
---|
| 201 | SEIActiveParameterSets* TEncGOP::xCreateSEIActiveParameterSets (TComSPS *sps) |
---|
| 202 | { |
---|
| 203 | SEIActiveParameterSets *seiActiveParameterSets = new SEIActiveParameterSets(); |
---|
| 204 | seiActiveParameterSets->activeVPSId = m_pcCfg->getVPS()->getVPSId(); |
---|
[713] | 205 | seiActiveParameterSets->m_selfContainedCvsFlag = false; |
---|
| 206 | seiActiveParameterSets->m_noParameterSetUpdateFlag = false; |
---|
[906] | 207 | #if !R0247_SEI_ACTIVE |
---|
[313] | 208 | seiActiveParameterSets->numSpsIdsMinus1 = 0; |
---|
[713] | 209 | seiActiveParameterSets->activeSeqParameterSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1); |
---|
| 210 | seiActiveParameterSets->activeSeqParameterSetId[0] = sps->getSPSId(); |
---|
[906] | 211 | #else |
---|
| 212 | seiActiveParameterSets->numSpsIdsMinus1 = m_pcCfg->getNumLayer()-1; |
---|
| 213 | seiActiveParameterSets->activeSeqParameterSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1); |
---|
| 214 | seiActiveParameterSets->layerSpsIdx.resize(seiActiveParameterSets->numSpsIdsMinus1+ 1); |
---|
| 215 | for (Int c=0; c <= seiActiveParameterSets->numSpsIdsMinus1; c++) |
---|
| 216 | { |
---|
| 217 | seiActiveParameterSets->activeSeqParameterSetId[c] = c; |
---|
| 218 | } |
---|
| 219 | for (Int c=1; c <= seiActiveParameterSets->numSpsIdsMinus1; c++) |
---|
| 220 | { |
---|
| 221 | seiActiveParameterSets->layerSpsIdx[c] = c; |
---|
| 222 | } |
---|
| 223 | #endif |
---|
[313] | 224 | return seiActiveParameterSets; |
---|
| 225 | } |
---|
| 226 | |
---|
| 227 | SEIFramePacking* TEncGOP::xCreateSEIFramePacking() |
---|
| 228 | { |
---|
| 229 | SEIFramePacking *seiFramePacking = new SEIFramePacking(); |
---|
| 230 | seiFramePacking->m_arrangementId = m_pcCfg->getFramePackingArrangementSEIId(); |
---|
| 231 | seiFramePacking->m_arrangementCancelFlag = 0; |
---|
| 232 | seiFramePacking->m_arrangementType = m_pcCfg->getFramePackingArrangementSEIType(); |
---|
| 233 | assert((seiFramePacking->m_arrangementType > 2) && (seiFramePacking->m_arrangementType < 6) ); |
---|
| 234 | seiFramePacking->m_quincunxSamplingFlag = m_pcCfg->getFramePackingArrangementSEIQuincunx(); |
---|
| 235 | seiFramePacking->m_contentInterpretationType = m_pcCfg->getFramePackingArrangementSEIInterpretation(); |
---|
| 236 | seiFramePacking->m_spatialFlippingFlag = 0; |
---|
| 237 | seiFramePacking->m_frame0FlippedFlag = 0; |
---|
| 238 | seiFramePacking->m_fieldViewsFlag = (seiFramePacking->m_arrangementType == 2); |
---|
| 239 | seiFramePacking->m_currentFrameIsFrame0Flag = ((seiFramePacking->m_arrangementType == 5) && m_iNumPicCoded&1); |
---|
| 240 | seiFramePacking->m_frame0SelfContainedFlag = 0; |
---|
| 241 | seiFramePacking->m_frame1SelfContainedFlag = 0; |
---|
| 242 | seiFramePacking->m_frame0GridPositionX = 0; |
---|
| 243 | seiFramePacking->m_frame0GridPositionY = 0; |
---|
| 244 | seiFramePacking->m_frame1GridPositionX = 0; |
---|
| 245 | seiFramePacking->m_frame1GridPositionY = 0; |
---|
| 246 | seiFramePacking->m_arrangementReservedByte = 0; |
---|
| 247 | seiFramePacking->m_arrangementPersistenceFlag = true; |
---|
| 248 | seiFramePacking->m_upsampledAspectRatio = 0; |
---|
| 249 | return seiFramePacking; |
---|
| 250 | } |
---|
| 251 | |
---|
| 252 | SEIDisplayOrientation* TEncGOP::xCreateSEIDisplayOrientation() |
---|
| 253 | { |
---|
| 254 | SEIDisplayOrientation *seiDisplayOrientation = new SEIDisplayOrientation(); |
---|
| 255 | seiDisplayOrientation->cancelFlag = false; |
---|
| 256 | seiDisplayOrientation->horFlip = false; |
---|
| 257 | seiDisplayOrientation->verFlip = false; |
---|
| 258 | seiDisplayOrientation->anticlockwiseRotation = m_pcCfg->getDisplayOrientationSEIAngle(); |
---|
| 259 | return seiDisplayOrientation; |
---|
| 260 | } |
---|
| 261 | |
---|
| 262 | SEIToneMappingInfo* TEncGOP::xCreateSEIToneMappingInfo() |
---|
| 263 | { |
---|
| 264 | SEIToneMappingInfo *seiToneMappingInfo = new SEIToneMappingInfo(); |
---|
| 265 | seiToneMappingInfo->m_toneMapId = m_pcCfg->getTMISEIToneMapId(); |
---|
| 266 | seiToneMappingInfo->m_toneMapCancelFlag = m_pcCfg->getTMISEIToneMapCancelFlag(); |
---|
| 267 | seiToneMappingInfo->m_toneMapPersistenceFlag = m_pcCfg->getTMISEIToneMapPersistenceFlag(); |
---|
| 268 | |
---|
| 269 | seiToneMappingInfo->m_codedDataBitDepth = m_pcCfg->getTMISEICodedDataBitDepth(); |
---|
| 270 | assert(seiToneMappingInfo->m_codedDataBitDepth >= 8 && seiToneMappingInfo->m_codedDataBitDepth <= 14); |
---|
| 271 | seiToneMappingInfo->m_targetBitDepth = m_pcCfg->getTMISEITargetBitDepth(); |
---|
| 272 | assert( seiToneMappingInfo->m_targetBitDepth >= 1 && seiToneMappingInfo->m_targetBitDepth <= 17 ); |
---|
| 273 | seiToneMappingInfo->m_modelId = m_pcCfg->getTMISEIModelID(); |
---|
| 274 | assert(seiToneMappingInfo->m_modelId >=0 &&seiToneMappingInfo->m_modelId<=4); |
---|
| 275 | |
---|
| 276 | switch( seiToneMappingInfo->m_modelId) |
---|
| 277 | { |
---|
| 278 | case 0: |
---|
| 279 | { |
---|
| 280 | seiToneMappingInfo->m_minValue = m_pcCfg->getTMISEIMinValue(); |
---|
| 281 | seiToneMappingInfo->m_maxValue = m_pcCfg->getTMISEIMaxValue(); |
---|
| 282 | break; |
---|
| 283 | } |
---|
| 284 | case 1: |
---|
| 285 | { |
---|
| 286 | seiToneMappingInfo->m_sigmoidMidpoint = m_pcCfg->getTMISEISigmoidMidpoint(); |
---|
| 287 | seiToneMappingInfo->m_sigmoidWidth = m_pcCfg->getTMISEISigmoidWidth(); |
---|
| 288 | break; |
---|
| 289 | } |
---|
| 290 | case 2: |
---|
| 291 | { |
---|
| 292 | UInt num = 1u<<(seiToneMappingInfo->m_targetBitDepth); |
---|
| 293 | seiToneMappingInfo->m_startOfCodedInterval.resize(num); |
---|
| 294 | Int* ptmp = m_pcCfg->getTMISEIStartOfCodedInterva(); |
---|
| 295 | if(ptmp) |
---|
| 296 | { |
---|
| 297 | for(int i=0; i<num;i++) |
---|
| 298 | { |
---|
| 299 | seiToneMappingInfo->m_startOfCodedInterval[i] = ptmp[i]; |
---|
| 300 | } |
---|
| 301 | } |
---|
| 302 | break; |
---|
| 303 | } |
---|
| 304 | case 3: |
---|
| 305 | { |
---|
| 306 | seiToneMappingInfo->m_numPivots = m_pcCfg->getTMISEINumPivots(); |
---|
| 307 | seiToneMappingInfo->m_codedPivotValue.resize(seiToneMappingInfo->m_numPivots); |
---|
| 308 | seiToneMappingInfo->m_targetPivotValue.resize(seiToneMappingInfo->m_numPivots); |
---|
| 309 | Int* ptmpcoded = m_pcCfg->getTMISEICodedPivotValue(); |
---|
| 310 | Int* ptmptarget = m_pcCfg->getTMISEITargetPivotValue(); |
---|
| 311 | if(ptmpcoded&&ptmptarget) |
---|
| 312 | { |
---|
| 313 | for(int i=0; i<(seiToneMappingInfo->m_numPivots);i++) |
---|
| 314 | { |
---|
| 315 | seiToneMappingInfo->m_codedPivotValue[i]=ptmpcoded[i]; |
---|
| 316 | seiToneMappingInfo->m_targetPivotValue[i]=ptmptarget[i]; |
---|
| 317 | } |
---|
| 318 | } |
---|
| 319 | break; |
---|
| 320 | } |
---|
| 321 | case 4: |
---|
| 322 | { |
---|
| 323 | seiToneMappingInfo->m_cameraIsoSpeedIdc = m_pcCfg->getTMISEICameraIsoSpeedIdc(); |
---|
| 324 | seiToneMappingInfo->m_cameraIsoSpeedValue = m_pcCfg->getTMISEICameraIsoSpeedValue(); |
---|
| 325 | assert( seiToneMappingInfo->m_cameraIsoSpeedValue !=0 ); |
---|
[713] | 326 | seiToneMappingInfo->m_exposureIndexIdc = m_pcCfg->getTMISEIExposurIndexIdc(); |
---|
| 327 | seiToneMappingInfo->m_exposureIndexValue = m_pcCfg->getTMISEIExposurIndexValue(); |
---|
| 328 | assert( seiToneMappingInfo->m_exposureIndexValue !=0 ); |
---|
[313] | 329 | seiToneMappingInfo->m_exposureCompensationValueSignFlag = m_pcCfg->getTMISEIExposureCompensationValueSignFlag(); |
---|
| 330 | seiToneMappingInfo->m_exposureCompensationValueNumerator = m_pcCfg->getTMISEIExposureCompensationValueNumerator(); |
---|
| 331 | seiToneMappingInfo->m_exposureCompensationValueDenomIdc = m_pcCfg->getTMISEIExposureCompensationValueDenomIdc(); |
---|
| 332 | seiToneMappingInfo->m_refScreenLuminanceWhite = m_pcCfg->getTMISEIRefScreenLuminanceWhite(); |
---|
| 333 | seiToneMappingInfo->m_extendedRangeWhiteLevel = m_pcCfg->getTMISEIExtendedRangeWhiteLevel(); |
---|
| 334 | assert( seiToneMappingInfo->m_extendedRangeWhiteLevel >= 100 ); |
---|
| 335 | seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue = m_pcCfg->getTMISEINominalBlackLevelLumaCodeValue(); |
---|
| 336 | seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue = m_pcCfg->getTMISEINominalWhiteLevelLumaCodeValue(); |
---|
| 337 | assert( seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue > seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue ); |
---|
| 338 | seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue = m_pcCfg->getTMISEIExtendedWhiteLevelLumaCodeValue(); |
---|
| 339 | assert( seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue >= seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue ); |
---|
| 340 | break; |
---|
| 341 | } |
---|
| 342 | default: |
---|
| 343 | { |
---|
| 344 | assert(!"Undefined SEIToneMapModelId"); |
---|
| 345 | break; |
---|
| 346 | } |
---|
| 347 | } |
---|
| 348 | return seiToneMappingInfo; |
---|
| 349 | } |
---|
| 350 | |
---|
[815] | 351 | #if P0050_KNEE_FUNCTION_SEI |
---|
| 352 | SEIKneeFunctionInfo* TEncGOP::xCreateSEIKneeFunctionInfo() |
---|
| 353 | { |
---|
| 354 | SEIKneeFunctionInfo *seiKneeFunctionInfo = new SEIKneeFunctionInfo(); |
---|
| 355 | seiKneeFunctionInfo->m_kneeId = m_pcCfg->getKneeSEIId(); |
---|
| 356 | seiKneeFunctionInfo->m_kneeCancelFlag = m_pcCfg->getKneeSEICancelFlag(); |
---|
| 357 | if ( !seiKneeFunctionInfo->m_kneeCancelFlag ) |
---|
| 358 | { |
---|
| 359 | seiKneeFunctionInfo->m_kneePersistenceFlag = m_pcCfg->getKneeSEIPersistenceFlag(); |
---|
| 360 | seiKneeFunctionInfo->m_kneeMappingFlag = m_pcCfg->getKneeSEIMappingFlag(); |
---|
| 361 | seiKneeFunctionInfo->m_kneeInputDrange = m_pcCfg->getKneeSEIInputDrange(); |
---|
| 362 | seiKneeFunctionInfo->m_kneeInputDispLuminance = m_pcCfg->getKneeSEIInputDispLuminance(); |
---|
| 363 | seiKneeFunctionInfo->m_kneeOutputDrange = m_pcCfg->getKneeSEIOutputDrange(); |
---|
| 364 | seiKneeFunctionInfo->m_kneeOutputDispLuminance = m_pcCfg->getKneeSEIOutputDispLuminance(); |
---|
| 365 | |
---|
| 366 | seiKneeFunctionInfo->m_kneeNumKneePointsMinus1 = m_pcCfg->getKneeSEINumKneePointsMinus1(); |
---|
| 367 | Int* piInputKneePoint = m_pcCfg->getKneeSEIInputKneePoint(); |
---|
| 368 | Int* piOutputKneePoint = m_pcCfg->getKneeSEIOutputKneePoint(); |
---|
| 369 | if(piInputKneePoint&&piOutputKneePoint) |
---|
| 370 | { |
---|
| 371 | seiKneeFunctionInfo->m_kneeInputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1); |
---|
| 372 | seiKneeFunctionInfo->m_kneeOutputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1); |
---|
| 373 | for(Int i=0; i<=seiKneeFunctionInfo->m_kneeNumKneePointsMinus1; i++) |
---|
| 374 | { |
---|
| 375 | seiKneeFunctionInfo->m_kneeInputKneePoint[i] = piInputKneePoint[i]; |
---|
| 376 | seiKneeFunctionInfo->m_kneeOutputKneePoint[i] = piOutputKneePoint[i]; |
---|
| 377 | } |
---|
| 378 | } |
---|
| 379 | } |
---|
| 380 | return seiKneeFunctionInfo; |
---|
| 381 | } |
---|
| 382 | #endif |
---|
| 383 | |
---|
[906] | 384 | #if Q0074_COLOUR_REMAPPING_SEI |
---|
| 385 | SEIColourRemappingInfo* TEncGOP::xCreateSEIColourRemappingInfo() |
---|
[713] | 386 | { |
---|
[906] | 387 | SEIColourRemappingInfo *seiColourRemappingInfo = new SEIColourRemappingInfo(); |
---|
| 388 | seiColourRemappingInfo->m_colourRemapId = m_pcCfg->getCRISEIId(); |
---|
| 389 | seiColourRemappingInfo->m_colourRemapCancelFlag = m_pcCfg->getCRISEICancelFlag(); |
---|
| 390 | if( !seiColourRemappingInfo->m_colourRemapCancelFlag ) |
---|
[713] | 391 | { |
---|
[906] | 392 | seiColourRemappingInfo->m_colourRemapPersistenceFlag = m_pcCfg->getCRISEIPersistenceFlag(); |
---|
| 393 | seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag = m_pcCfg->getCRISEIVideoSignalInfoPresentFlag(); |
---|
| 394 | if( seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag ) |
---|
[713] | 395 | { |
---|
[906] | 396 | seiColourRemappingInfo->m_colourRemapFullRangeFlag = m_pcCfg->getCRISEIFullRangeFlag(); |
---|
| 397 | seiColourRemappingInfo->m_colourRemapPrimaries = m_pcCfg->getCRISEIPrimaries(); |
---|
| 398 | seiColourRemappingInfo->m_colourRemapTransferFunction = m_pcCfg->getCRISEITransferFunction(); |
---|
| 399 | seiColourRemappingInfo->m_colourRemapMatrixCoefficients = m_pcCfg->getCRISEIMatrixCoefficients(); |
---|
[713] | 400 | } |
---|
[906] | 401 | seiColourRemappingInfo->m_colourRemapInputBitDepth = m_pcCfg->getCRISEIInputBitDepth(); |
---|
| 402 | seiColourRemappingInfo->m_colourRemapBitDepth = m_pcCfg->getCRISEIBitDepth(); |
---|
| 403 | for( Int c=0 ; c<3 ; c++ ) |
---|
[713] | 404 | { |
---|
[906] | 405 | seiColourRemappingInfo->m_preLutNumValMinus1[c] = m_pcCfg->getCRISEIPreLutNumValMinus1(c); |
---|
| 406 | if( seiColourRemappingInfo->m_preLutNumValMinus1[c]>0 ) |
---|
| 407 | { |
---|
| 408 | seiColourRemappingInfo->m_preLutCodedValue[c].resize(seiColourRemappingInfo->m_preLutNumValMinus1[c]+1); |
---|
| 409 | seiColourRemappingInfo->m_preLutTargetValue[c].resize(seiColourRemappingInfo->m_preLutNumValMinus1[c]+1); |
---|
| 410 | for( Int i=0 ; i<=seiColourRemappingInfo->m_preLutNumValMinus1[c] ; i++) |
---|
| 411 | { |
---|
| 412 | seiColourRemappingInfo->m_preLutCodedValue[c][i] = (m_pcCfg->getCRISEIPreLutCodedValue(c))[i]; |
---|
| 413 | seiColourRemappingInfo->m_preLutTargetValue[c][i] = (m_pcCfg->getCRISEIPreLutTargetValue(c))[i]; |
---|
| 414 | } |
---|
| 415 | } |
---|
[713] | 416 | } |
---|
[906] | 417 | seiColourRemappingInfo->m_colourRemapMatrixPresentFlag = m_pcCfg->getCRISEIMatrixPresentFlag(); |
---|
| 418 | if( seiColourRemappingInfo->m_colourRemapMatrixPresentFlag ) |
---|
[713] | 419 | { |
---|
[906] | 420 | seiColourRemappingInfo->m_log2MatrixDenom = m_pcCfg->getCRISEILog2MatrixDenom(); |
---|
| 421 | for( Int c=0 ; c<3 ; c++ ) |
---|
| 422 | for( Int i=0 ; i<3 ; i++ ) |
---|
| 423 | seiColourRemappingInfo->m_colourRemapCoeffs[c][i] = (m_pcCfg->getCRISEICoeffs(c))[i]; |
---|
| 424 | } |
---|
| 425 | for( Int c=0 ; c<3 ; c++ ) |
---|
| 426 | { |
---|
| 427 | seiColourRemappingInfo->m_postLutNumValMinus1[c] = m_pcCfg->getCRISEIPostLutNumValMinus1(c); |
---|
| 428 | if( seiColourRemappingInfo->m_postLutNumValMinus1[c]>0 ) |
---|
[713] | 429 | { |
---|
[906] | 430 | seiColourRemappingInfo->m_postLutCodedValue[c].resize(seiColourRemappingInfo->m_postLutNumValMinus1[c]+1); |
---|
| 431 | seiColourRemappingInfo->m_postLutTargetValue[c].resize(seiColourRemappingInfo->m_postLutNumValMinus1[c]+1); |
---|
| 432 | for( Int i=0 ; i<=seiColourRemappingInfo->m_postLutNumValMinus1[c] ; i++) |
---|
| 433 | { |
---|
| 434 | seiColourRemappingInfo->m_postLutCodedValue[c][i] = (m_pcCfg->getCRISEIPostLutCodedValue(c))[i]; |
---|
| 435 | seiColourRemappingInfo->m_postLutTargetValue[c][i] = (m_pcCfg->getCRISEIPostLutTargetValue(c))[i]; |
---|
| 436 | } |
---|
[713] | 437 | } |
---|
| 438 | } |
---|
| 439 | } |
---|
[906] | 440 | return seiColourRemappingInfo; |
---|
[713] | 441 | } |
---|
| 442 | #endif |
---|
| 443 | |
---|
[313] | 444 | Void TEncGOP::xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps) |
---|
| 445 | { |
---|
| 446 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); |
---|
| 447 | |
---|
[906] | 448 | if(m_pcCfg->getActiveParameterSetsSEIEnabled() |
---|
| 449 | #if R0247_SEI_ACTIVE |
---|
| 450 | && m_layerId == 0 |
---|
| 451 | #endif |
---|
| 452 | ) |
---|
[313] | 453 | { |
---|
| 454 | SEIActiveParameterSets *sei = xCreateSEIActiveParameterSets (sps); |
---|
| 455 | |
---|
| 456 | //nalu = NALUnit(NAL_UNIT_SEI); |
---|
| 457 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
[644] | 458 | #if O0164_MULTI_LAYER_HRD |
---|
| 459 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); |
---|
| 460 | #else |
---|
[313] | 461 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); |
---|
[644] | 462 | #endif |
---|
[313] | 463 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 464 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 465 | delete sei; |
---|
| 466 | m_activeParameterSetSEIPresentInAU = true; |
---|
| 467 | } |
---|
| 468 | |
---|
| 469 | if(m_pcCfg->getFramePackingArrangementSEIEnabled()) |
---|
| 470 | { |
---|
| 471 | SEIFramePacking *sei = xCreateSEIFramePacking (); |
---|
| 472 | |
---|
| 473 | nalu = NALUnit(NAL_UNIT_PREFIX_SEI); |
---|
| 474 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
[644] | 475 | #if O0164_MULTI_LAYER_HRD |
---|
| 476 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); |
---|
| 477 | #else |
---|
[313] | 478 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); |
---|
[644] | 479 | #endif |
---|
[313] | 480 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 481 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 482 | delete sei; |
---|
| 483 | } |
---|
| 484 | if (m_pcCfg->getDisplayOrientationSEIAngle()) |
---|
| 485 | { |
---|
| 486 | SEIDisplayOrientation *sei = xCreateSEIDisplayOrientation(); |
---|
| 487 | |
---|
| 488 | nalu = NALUnit(NAL_UNIT_PREFIX_SEI); |
---|
| 489 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
[644] | 490 | #if O0164_MULTI_LAYER_HRD |
---|
| 491 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); |
---|
| 492 | #else |
---|
[313] | 493 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); |
---|
[644] | 494 | #endif |
---|
[313] | 495 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 496 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 497 | delete sei; |
---|
| 498 | } |
---|
| 499 | if(m_pcCfg->getToneMappingInfoSEIEnabled()) |
---|
| 500 | { |
---|
| 501 | SEIToneMappingInfo *sei = xCreateSEIToneMappingInfo (); |
---|
| 502 | |
---|
| 503 | nalu = NALUnit(NAL_UNIT_PREFIX_SEI); |
---|
| 504 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
[644] | 505 | #if O0164_MULTI_LAYER_HRD |
---|
| 506 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); |
---|
| 507 | #else |
---|
[313] | 508 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); |
---|
[644] | 509 | #endif |
---|
[313] | 510 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 511 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 512 | delete sei; |
---|
| 513 | } |
---|
[815] | 514 | #if P0050_KNEE_FUNCTION_SEI |
---|
| 515 | if(m_pcCfg->getKneeSEIEnabled()) |
---|
| 516 | { |
---|
| 517 | SEIKneeFunctionInfo *sei = xCreateSEIKneeFunctionInfo(); |
---|
| 518 | |
---|
| 519 | nalu = NALUnit(NAL_UNIT_PREFIX_SEI); |
---|
| 520 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 521 | #if O0164_MULTI_LAYER_HRD |
---|
| 522 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); |
---|
| 523 | #else |
---|
| 524 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); |
---|
| 525 | #endif |
---|
| 526 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 527 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 528 | delete sei; |
---|
| 529 | } |
---|
| 530 | #endif |
---|
[906] | 531 | #if Q0074_COLOUR_REMAPPING_SEI |
---|
| 532 | if(strlen(m_pcCfg->getCRISEIFile())) |
---|
[713] | 533 | { |
---|
[906] | 534 | SEIColourRemappingInfo *sei = xCreateSEIColourRemappingInfo (); |
---|
[713] | 535 | |
---|
| 536 | #if SVC_EXTENSION |
---|
[906] | 537 | nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, sps->getLayerId()); // SEI-CRI is applied per layer |
---|
[713] | 538 | #else |
---|
| 539 | nalu = NALUnit(NAL_UNIT_PREFIX_SEI); |
---|
| 540 | #endif |
---|
| 541 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 542 | #if O0164_MULTI_LAYER_HRD |
---|
| 543 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); |
---|
| 544 | #else |
---|
| 545 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); |
---|
| 546 | #endif |
---|
| 547 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 548 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 549 | delete sei; |
---|
| 550 | } |
---|
| 551 | #endif |
---|
[595] | 552 | |
---|
| 553 | #if SVC_EXTENSION |
---|
| 554 | #if LAYERS_NOT_PRESENT_SEI |
---|
| 555 | if(m_pcCfg->getLayersNotPresentSEIEnabled()) |
---|
| 556 | { |
---|
| 557 | SEILayersNotPresent *sei = xCreateSEILayersNotPresent (); |
---|
| 558 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
[644] | 559 | #if O0164_MULTI_LAYER_HRD |
---|
| 560 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); |
---|
| 561 | #else |
---|
[595] | 562 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); |
---|
[644] | 563 | #endif |
---|
[595] | 564 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 565 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 566 | delete sei; |
---|
| 567 | } |
---|
| 568 | #endif |
---|
| 569 | |
---|
[442] | 570 | #if N0383_IL_CONSTRAINED_TILE_SETS_SEI |
---|
| 571 | if(m_pcCfg->getInterLayerConstrainedTileSetsSEIEnabled()) |
---|
| 572 | { |
---|
| 573 | SEIInterLayerConstrainedTileSets *sei = xCreateSEIInterLayerConstrainedTileSets (); |
---|
| 574 | |
---|
| 575 | nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, m_pcCfg->getNumLayer()-1); // For highest layer |
---|
| 576 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
[644] | 577 | #if O0164_MULTI_LAYER_HRD |
---|
| 578 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); |
---|
| 579 | #else |
---|
[442] | 580 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); |
---|
[644] | 581 | #endif |
---|
[442] | 582 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 583 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 584 | delete sei; |
---|
| 585 | } |
---|
| 586 | #endif |
---|
[595] | 587 | #endif //SVC_EXTENSION |
---|
[313] | 588 | } |
---|
| 589 | |
---|
| 590 | // ==================================================================================================================== |
---|
| 591 | // Public member functions |
---|
| 592 | // ==================================================================================================================== |
---|
| 593 | #if SVC_EXTENSION |
---|
[442] | 594 | Void TEncGOP::compressGOP( Int iPicIdInGOP, Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP, Bool isField, Bool isTff) |
---|
[313] | 595 | #else |
---|
[442] | 596 | Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP, Bool isField, Bool isTff) |
---|
[313] | 597 | #endif |
---|
| 598 | { |
---|
| 599 | TComPic* pcPic; |
---|
| 600 | TComPicYuv* pcPicYuvRecOut; |
---|
| 601 | TComSlice* pcSlice; |
---|
| 602 | TComOutputBitstream *pcBitstreamRedirect; |
---|
| 603 | pcBitstreamRedirect = new TComOutputBitstream; |
---|
| 604 | AccessUnit::iterator itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted |
---|
| 605 | UInt uiOneBitstreamPerSliceLength = 0; |
---|
| 606 | TEncSbac* pcSbacCoders = NULL; |
---|
| 607 | TComOutputBitstream* pcSubstreamsOut = NULL; |
---|
| 608 | |
---|
[442] | 609 | xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut, isField ); |
---|
[313] | 610 | |
---|
| 611 | m_iNumPicCoded = 0; |
---|
| 612 | SEIPictureTiming pictureTimingSEI; |
---|
| 613 | Bool writeSOP = m_pcCfg->getSOPDescriptionSEIEnabled(); |
---|
| 614 | // Initialize Scalable Nesting SEI with single layer values |
---|
| 615 | SEIScalableNesting scalableNestingSEI; |
---|
| 616 | scalableNestingSEI.m_bitStreamSubsetFlag = 1; // If the nested SEI messages are picture buffereing SEI mesages, picure timing SEI messages or sub-picture timing SEI messages, bitstream_subset_flag shall be equal to 1 |
---|
| 617 | scalableNestingSEI.m_nestingOpFlag = 0; |
---|
| 618 | scalableNestingSEI.m_nestingNumOpsMinus1 = 0; //nesting_num_ops_minus1 |
---|
| 619 | scalableNestingSEI.m_allLayersFlag = 0; |
---|
| 620 | scalableNestingSEI.m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1; //nesting_no_op_max_temporal_id_plus1 |
---|
| 621 | scalableNestingSEI.m_nestingNumLayersMinus1 = 1 - 1; //nesting_num_layers_minus1 |
---|
| 622 | scalableNestingSEI.m_nestingLayerId[0] = 0; |
---|
| 623 | scalableNestingSEI.m_callerOwnsSEIs = true; |
---|
| 624 | Int picSptDpbOutputDuDelay = 0; |
---|
| 625 | UInt *accumBitsDU = NULL; |
---|
| 626 | UInt *accumNalsDU = NULL; |
---|
| 627 | SEIDecodingUnitInfo decodingUnitInfoSEI; |
---|
[713] | 628 | #if EFFICIENT_FIELD_IRAP |
---|
| 629 | Int IRAPGOPid = -1; |
---|
| 630 | Bool IRAPtoReorder = false; |
---|
| 631 | Bool swapIRAPForward = false; |
---|
| 632 | if(isField) |
---|
| 633 | { |
---|
| 634 | Int pocCurr; |
---|
[313] | 635 | #if SVC_EXTENSION |
---|
[713] | 636 | for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ ) |
---|
| 637 | #else |
---|
| 638 | for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ ) |
---|
| 639 | #endif |
---|
| 640 | { |
---|
| 641 | // determine actual POC |
---|
| 642 | if(iPOCLast == 0) //case first frame or first top field |
---|
| 643 | { |
---|
| 644 | pocCurr=0; |
---|
| 645 | } |
---|
| 646 | else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value |
---|
| 647 | { |
---|
| 648 | pocCurr = 1; |
---|
| 649 | } |
---|
| 650 | else |
---|
| 651 | { |
---|
| 652 | pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField; |
---|
| 653 | } |
---|
| 654 | |
---|
| 655 | // check if POC corresponds to IRAP |
---|
| 656 | NalUnitType tmpUnitType = getNalUnitType(pocCurr, m_iLastIDR, isField); |
---|
| 657 | if(tmpUnitType >= NAL_UNIT_CODED_SLICE_BLA_W_LP && tmpUnitType <= NAL_UNIT_CODED_SLICE_CRA) // if picture is an IRAP |
---|
| 658 | { |
---|
| 659 | if(pocCurr%2 == 0 && iGOPid < m_iGopSize-1 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid+1).m_POC-1) |
---|
| 660 | { // if top field and following picture in enc order is associated bottom field |
---|
| 661 | IRAPGOPid = iGOPid; |
---|
| 662 | IRAPtoReorder = true; |
---|
| 663 | swapIRAPForward = true; |
---|
| 664 | break; |
---|
| 665 | } |
---|
| 666 | if(pocCurr%2 != 0 && iGOPid > 0 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid-1).m_POC+1) |
---|
| 667 | { |
---|
| 668 | // if picture is an IRAP remember to process it first |
---|
| 669 | IRAPGOPid = iGOPid; |
---|
| 670 | IRAPtoReorder = true; |
---|
| 671 | swapIRAPForward = false; |
---|
| 672 | break; |
---|
| 673 | } |
---|
| 674 | } |
---|
| 675 | } |
---|
| 676 | } |
---|
| 677 | #endif |
---|
| 678 | #if SVC_EXTENSION |
---|
[313] | 679 | for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ ) |
---|
| 680 | #else |
---|
| 681 | for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ ) |
---|
| 682 | #endif |
---|
| 683 | { |
---|
[713] | 684 | #if EFFICIENT_FIELD_IRAP |
---|
| 685 | if(IRAPtoReorder) |
---|
| 686 | { |
---|
| 687 | if(swapIRAPForward) |
---|
| 688 | { |
---|
| 689 | if(iGOPid == IRAPGOPid) |
---|
| 690 | { |
---|
| 691 | iGOPid = IRAPGOPid +1; |
---|
| 692 | } |
---|
| 693 | else if(iGOPid == IRAPGOPid +1) |
---|
| 694 | { |
---|
| 695 | iGOPid = IRAPGOPid; |
---|
| 696 | } |
---|
| 697 | } |
---|
| 698 | else |
---|
| 699 | { |
---|
| 700 | if(iGOPid == IRAPGOPid -1) |
---|
| 701 | { |
---|
| 702 | iGOPid = IRAPGOPid; |
---|
| 703 | } |
---|
| 704 | else if(iGOPid == IRAPGOPid) |
---|
| 705 | { |
---|
| 706 | iGOPid = IRAPGOPid -1; |
---|
| 707 | } |
---|
| 708 | } |
---|
| 709 | } |
---|
| 710 | #endif |
---|
[313] | 711 | UInt uiColDir = 1; |
---|
| 712 | //-- For time output for each slice |
---|
| 713 | long iBeforeTime = clock(); |
---|
| 714 | |
---|
| 715 | //select uiColDir |
---|
| 716 | Int iCloseLeft=1, iCloseRight=-1; |
---|
| 717 | for(Int i = 0; i<m_pcCfg->getGOPEntry(iGOPid).m_numRefPics; i++) |
---|
| 718 | { |
---|
| 719 | Int iRef = m_pcCfg->getGOPEntry(iGOPid).m_referencePics[i]; |
---|
| 720 | if(iRef>0&&(iRef<iCloseRight||iCloseRight==-1)) |
---|
| 721 | { |
---|
| 722 | iCloseRight=iRef; |
---|
| 723 | } |
---|
| 724 | else if(iRef<0&&(iRef>iCloseLeft||iCloseLeft==1)) |
---|
| 725 | { |
---|
| 726 | iCloseLeft=iRef; |
---|
| 727 | } |
---|
| 728 | } |
---|
| 729 | if(iCloseRight>-1) |
---|
| 730 | { |
---|
| 731 | iCloseRight=iCloseRight+m_pcCfg->getGOPEntry(iGOPid).m_POC-1; |
---|
| 732 | } |
---|
| 733 | if(iCloseLeft<1) |
---|
| 734 | { |
---|
| 735 | iCloseLeft=iCloseLeft+m_pcCfg->getGOPEntry(iGOPid).m_POC-1; |
---|
| 736 | while(iCloseLeft<0) |
---|
| 737 | { |
---|
| 738 | iCloseLeft+=m_iGopSize; |
---|
| 739 | } |
---|
| 740 | } |
---|
| 741 | Int iLeftQP=0, iRightQP=0; |
---|
| 742 | for(Int i=0; i<m_iGopSize; i++) |
---|
| 743 | { |
---|
| 744 | if(m_pcCfg->getGOPEntry(i).m_POC==(iCloseLeft%m_iGopSize)+1) |
---|
| 745 | { |
---|
| 746 | iLeftQP= m_pcCfg->getGOPEntry(i).m_QPOffset; |
---|
| 747 | } |
---|
| 748 | if (m_pcCfg->getGOPEntry(i).m_POC==(iCloseRight%m_iGopSize)+1) |
---|
| 749 | { |
---|
| 750 | iRightQP=m_pcCfg->getGOPEntry(i).m_QPOffset; |
---|
| 751 | } |
---|
| 752 | } |
---|
| 753 | if(iCloseRight>-1&&iRightQP<iLeftQP) |
---|
| 754 | { |
---|
| 755 | uiColDir=0; |
---|
| 756 | } |
---|
| 757 | |
---|
| 758 | /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding |
---|
[442] | 759 | Int iTimeOffset; |
---|
| 760 | Int pocCurr; |
---|
| 761 | |
---|
| 762 | if(iPOCLast == 0) //case first frame or first top field |
---|
[313] | 763 | { |
---|
| 764 | pocCurr=0; |
---|
| 765 | iTimeOffset = 1; |
---|
| 766 | } |
---|
[442] | 767 | else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value |
---|
| 768 | { |
---|
| 769 | pocCurr = 1; |
---|
| 770 | iTimeOffset = 1; |
---|
| 771 | } |
---|
| 772 | else |
---|
| 773 | { |
---|
| 774 | pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField; |
---|
| 775 | iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC; |
---|
| 776 | } |
---|
| 777 | |
---|
[313] | 778 | if(pocCurr>=m_pcCfg->getFramesToBeEncoded()) |
---|
| 779 | { |
---|
[713] | 780 | #if EFFICIENT_FIELD_IRAP |
---|
| 781 | if(IRAPtoReorder) |
---|
| 782 | { |
---|
| 783 | if(swapIRAPForward) |
---|
| 784 | { |
---|
| 785 | if(iGOPid == IRAPGOPid) |
---|
| 786 | { |
---|
| 787 | iGOPid = IRAPGOPid +1; |
---|
| 788 | IRAPtoReorder = false; |
---|
| 789 | } |
---|
| 790 | else if(iGOPid == IRAPGOPid +1) |
---|
| 791 | { |
---|
| 792 | iGOPid --; |
---|
| 793 | } |
---|
| 794 | } |
---|
| 795 | else |
---|
| 796 | { |
---|
| 797 | if(iGOPid == IRAPGOPid) |
---|
| 798 | { |
---|
| 799 | iGOPid = IRAPGOPid -1; |
---|
| 800 | } |
---|
| 801 | else if(iGOPid == IRAPGOPid -1) |
---|
| 802 | { |
---|
| 803 | iGOPid = IRAPGOPid; |
---|
| 804 | IRAPtoReorder = false; |
---|
| 805 | } |
---|
| 806 | } |
---|
| 807 | } |
---|
| 808 | #endif |
---|
[313] | 809 | continue; |
---|
| 810 | } |
---|
| 811 | |
---|
| 812 | #if M0040_ADAPTIVE_RESOLUTION_CHANGE |
---|
| 813 | if (m_pcEncTop->getAdaptiveResolutionChange() > 0 && ((m_layerId == 1 && pocCurr < m_pcEncTop->getAdaptiveResolutionChange()) || |
---|
| 814 | (m_layerId == 0 && pocCurr > m_pcEncTop->getAdaptiveResolutionChange())) ) |
---|
| 815 | { |
---|
| 816 | continue; |
---|
| 817 | } |
---|
| 818 | #endif |
---|
| 819 | |
---|
[595] | 820 | if( getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP ) |
---|
[313] | 821 | { |
---|
| 822 | m_iLastIDR = pocCurr; |
---|
| 823 | } |
---|
| 824 | // start a new access unit: create an entry in the list of output access units |
---|
| 825 | accessUnitsInGOP.push_back(AccessUnit()); |
---|
| 826 | AccessUnit& accessUnit = accessUnitsInGOP.back(); |
---|
[595] | 827 | xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField); |
---|
[313] | 828 | |
---|
| 829 | // Slice data initialization |
---|
| 830 | pcPic->clearSliceBuffer(); |
---|
| 831 | assert(pcPic->getNumAllocatedSlice() == 1); |
---|
| 832 | m_pcSliceEncoder->setSliceIdx(0); |
---|
| 833 | pcPic->setCurrSliceIdx(0); |
---|
| 834 | #if SVC_EXTENSION |
---|
| 835 | pcPic->setLayerId( m_layerId ); |
---|
[442] | 836 | m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), m_pcEncTop->getVPS(), isField ); |
---|
[313] | 837 | #else |
---|
[442] | 838 | m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), isField ); |
---|
[313] | 839 | #endif |
---|
| 840 | |
---|
[442] | 841 | //Set Frame/Field coding |
---|
| 842 | pcSlice->getPic()->setField(isField); |
---|
| 843 | |
---|
[595] | 844 | #if SVC_EXTENSION |
---|
[442] | 845 | #if POC_RESET_FLAG |
---|
| 846 | if( !pcSlice->getPocResetFlag() ) // For picture that are not reset, we should adjust the value of POC calculated from the configuration files. |
---|
| 847 | { |
---|
| 848 | // Subtract POC adjustment value until now. |
---|
| 849 | pcSlice->setPOC( pcSlice->getPOC() - m_pcEncTop->getPocAdjustmentValue() ); |
---|
| 850 | } |
---|
| 851 | else |
---|
| 852 | { |
---|
| 853 | // Check if this is the first slice in the picture |
---|
| 854 | // In the encoder, the POC values are copied along with copySliceInfo, so we only need |
---|
| 855 | // to do this for the first slice. |
---|
| 856 | Int pocAdjustValue = pcSlice->getPOC() - m_pcEncTop->getPocAdjustmentValue(); |
---|
| 857 | if( pcSlice->getSliceIdx() == 0 ) |
---|
| 858 | { |
---|
| 859 | TComList<TComPic*>::iterator iterPic = rcListPic.begin(); |
---|
| 860 | |
---|
| 861 | // Iterate through all picture in DPB |
---|
| 862 | while( iterPic != rcListPic.end() ) |
---|
| 863 | { |
---|
| 864 | TComPic *dpbPic = *iterPic; |
---|
| 865 | if( dpbPic->getPOC() == pocCurr ) |
---|
| 866 | { |
---|
| 867 | if( dpbPic->getReconMark() ) |
---|
| 868 | { |
---|
| 869 | assert( !( dpbPic->getSlice(0)->isReferenced() ) && !( dpbPic->getOutputMark() ) ); |
---|
| 870 | } |
---|
| 871 | } |
---|
| 872 | // Check if the picture pointed to by iterPic is either used for reference or |
---|
| 873 | // needed for output, are in the same layer, and not the current picture. |
---|
| 874 | if( /* ( ( dpbPic->getSlice(0)->isReferenced() ) || ( dpbPic->getOutputMark() ) ) |
---|
| 875 | && */ ( dpbPic->getLayerId() == pcSlice->getLayerId() ) |
---|
| 876 | && ( dpbPic->getReconMark() ) |
---|
| 877 | ) |
---|
| 878 | { |
---|
| 879 | for(Int i = dpbPic->getNumAllocatedSlice()-1; i >= 0; i--) |
---|
| 880 | { |
---|
| 881 | TComSlice *slice = dpbPic->getSlice(i); |
---|
| 882 | TComReferencePictureSet *rps = slice->getRPS(); |
---|
| 883 | slice->setPOC( dpbPic->getSlice(i)->getPOC() - pocAdjustValue ); |
---|
| 884 | |
---|
| 885 | // Also adjust the POC value stored in the RPS of each such slice |
---|
| 886 | for(Int j = rps->getNumberOfPictures(); j >= 0; j--) |
---|
| 887 | { |
---|
| 888 | rps->setPOC( j, rps->getPOC(j) - pocAdjustValue ); |
---|
| 889 | } |
---|
| 890 | // Also adjust the value of refPOC |
---|
| 891 | for(Int k = 0; k < 2; k++) // For List 0 and List 1 |
---|
| 892 | { |
---|
| 893 | RefPicList list = (k == 1) ? REF_PIC_LIST_1 : REF_PIC_LIST_0; |
---|
| 894 | for(Int j = 0; j < slice->getNumRefIdx(list); j++) |
---|
| 895 | { |
---|
| 896 | slice->setRefPOC( slice->getRefPOC(list, j) - pocAdjustValue, list, j); |
---|
| 897 | } |
---|
| 898 | } |
---|
| 899 | } |
---|
| 900 | } |
---|
| 901 | iterPic++; |
---|
| 902 | } |
---|
| 903 | m_pcEncTop->setPocAdjustmentValue( m_pcEncTop->getPocAdjustmentValue() + pocAdjustValue ); |
---|
| 904 | } |
---|
| 905 | pcSlice->setPocValueBeforeReset( pcSlice->getPOC() - m_pcEncTop->getPocAdjustmentValue() + pocAdjustValue ); |
---|
| 906 | pcSlice->setPOC( 0 ); |
---|
| 907 | } |
---|
| 908 | #endif |
---|
[815] | 909 | #if POC_RESET_IDC_ENCODER |
---|
| 910 | pcSlice->setPocValueBeforeReset( pocCurr ); |
---|
| 911 | // Check if the current picture is to be assigned as a reset picture |
---|
| 912 | determinePocResetIdc(pocCurr, pcSlice); |
---|
| 913 | |
---|
[906] | 914 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 915 | Bool pocResettingFlag = false; |
---|
| 916 | |
---|
| 917 | if (pcSlice->getPocResetIdc() != 0) |
---|
| 918 | { |
---|
| 919 | if (pcSlice->getVPS()->getVpsPocLsbAlignedFlag()) |
---|
| 920 | { |
---|
| 921 | pocResettingFlag = true; |
---|
| 922 | } |
---|
| 923 | else if (m_pcEncTop->getPocDecrementedInDPBFlag()) |
---|
| 924 | { |
---|
| 925 | pocResettingFlag = false; |
---|
| 926 | } |
---|
| 927 | else |
---|
| 928 | { |
---|
| 929 | pocResettingFlag = true; |
---|
| 930 | } |
---|
| 931 | } |
---|
| 932 | #endif |
---|
| 933 | |
---|
[815] | 934 | // If reset, do the following steps: |
---|
[906] | 935 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 936 | if( pocResettingFlag ) |
---|
| 937 | #else |
---|
[815] | 938 | if( pcSlice->getPocResetIdc() ) |
---|
[906] | 939 | #endif |
---|
[815] | 940 | { |
---|
| 941 | updatePocValuesOfPics(pocCurr, pcSlice); |
---|
| 942 | } |
---|
| 943 | else |
---|
| 944 | { |
---|
| 945 | // Check the base layer picture is IDR. If so, just set current POC equal to 0 (alignment of POC) |
---|
| 946 | if( ( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2) && ( pocCurr % m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshInterval() == 0 ) ) |
---|
| 947 | { |
---|
| 948 | m_pcEncTop->setPocAdjustmentValue( pocCurr ); |
---|
| 949 | } |
---|
| 950 | // else |
---|
| 951 | { |
---|
| 952 | // Just subtract POC by the current cumulative POC delta |
---|
| 953 | pcSlice->setPOC( pocCurr - m_pcEncTop->getPocAdjustmentValue() ); |
---|
| 954 | } |
---|
| 955 | |
---|
| 956 | Int maxPocLsb = 1 << pcSlice->getSPS()->getBitsForPOC(); |
---|
| 957 | pcSlice->setPocMsbVal( pcSlice->getPOC() - ( pcSlice->getPOC() & (maxPocLsb-1) ) ); |
---|
| 958 | } |
---|
| 959 | // Update the POC of current picture, pictures in the DPB, including references inside the reference pictures |
---|
| 960 | |
---|
| 961 | #endif |
---|
| 962 | |
---|
[540] | 963 | #if O0149_CROSS_LAYER_BLA_FLAG |
---|
[595] | 964 | if( m_layerId == 0 && (getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP) ) |
---|
[540] | 965 | { |
---|
| 966 | pcSlice->setCrossLayerBLAFlag(m_pcEncTop->getCrossLayerBLAFlag()); |
---|
| 967 | } |
---|
| 968 | else |
---|
| 969 | { |
---|
| 970 | pcSlice->setCrossLayerBLAFlag(false); |
---|
| 971 | } |
---|
| 972 | #endif |
---|
| 973 | #if NO_CLRAS_OUTPUT_FLAG |
---|
| 974 | if (m_layerId == 0 && |
---|
| 975 | (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP |
---|
| 976 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL |
---|
| 977 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP |
---|
| 978 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL |
---|
| 979 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP |
---|
| 980 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)) |
---|
| 981 | { |
---|
| 982 | if (m_bFirst) |
---|
| 983 | { |
---|
| 984 | m_pcEncTop->setNoClrasOutputFlag(true); |
---|
| 985 | } |
---|
| 986 | else if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP |
---|
| 987 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL |
---|
| 988 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP) |
---|
| 989 | { |
---|
| 990 | m_pcEncTop->setNoClrasOutputFlag(true); |
---|
| 991 | } |
---|
| 992 | #if O0149_CROSS_LAYER_BLA_FLAG |
---|
| 993 | else if ((pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP) && |
---|
| 994 | pcSlice->getCrossLayerBLAFlag()) |
---|
| 995 | { |
---|
| 996 | m_pcEncTop->setNoClrasOutputFlag(true); |
---|
| 997 | } |
---|
| 998 | #endif |
---|
| 999 | else |
---|
| 1000 | { |
---|
| 1001 | m_pcEncTop->setNoClrasOutputFlag(false); |
---|
| 1002 | } |
---|
| 1003 | if (m_pcEncTop->getNoClrasOutputFlag()) |
---|
| 1004 | { |
---|
| 1005 | for (UInt i = 0; i < m_pcCfg->getNumLayer(); i++) |
---|
| 1006 | { |
---|
| 1007 | m_ppcTEncTop[i]->setLayerInitializedFlag(false); |
---|
| 1008 | m_ppcTEncTop[i]->setFirstPicInLayerDecodedFlag(false); |
---|
| 1009 | } |
---|
| 1010 | } |
---|
| 1011 | } |
---|
| 1012 | #endif |
---|
[313] | 1013 | #if M0040_ADAPTIVE_RESOLUTION_CHANGE |
---|
| 1014 | if (m_pcEncTop->getAdaptiveResolutionChange() > 0 && m_layerId == 1 && pocCurr > m_pcEncTop->getAdaptiveResolutionChange()) |
---|
| 1015 | { |
---|
| 1016 | pcSlice->setActiveNumILRRefIdx(0); |
---|
| 1017 | pcSlice->setInterLayerPredEnabledFlag(false); |
---|
| 1018 | pcSlice->setMFMEnabledFlag(false); |
---|
| 1019 | } |
---|
| 1020 | #endif |
---|
[595] | 1021 | #endif //SVC_EXTENSION |
---|
[313] | 1022 | |
---|
| 1023 | pcSlice->setLastIDR(m_iLastIDR); |
---|
| 1024 | pcSlice->setSliceIdx(0); |
---|
| 1025 | //set default slice level flag to the same as SPS level flag |
---|
| 1026 | pcSlice->setLFCrossSliceBoundaryFlag( pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag() ); |
---|
| 1027 | pcSlice->setScalingList ( m_pcEncTop->getScalingList() ); |
---|
| 1028 | if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_OFF) |
---|
| 1029 | { |
---|
| 1030 | m_pcEncTop->getTrQuant()->setFlatScalingList(); |
---|
| 1031 | m_pcEncTop->getTrQuant()->setUseScalingList(false); |
---|
| 1032 | m_pcEncTop->getSPS()->setScalingListPresentFlag(false); |
---|
| 1033 | m_pcEncTop->getPPS()->setScalingListPresentFlag(false); |
---|
| 1034 | } |
---|
| 1035 | else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_DEFAULT) |
---|
| 1036 | { |
---|
[540] | 1037 | #if SCALINGLIST_INFERRING |
---|
| 1038 | // inferring of the scaling list can be moved to the config file |
---|
| 1039 | UInt refLayerId = 0; |
---|
[906] | 1040 | #if VPS_AVC_BL_FLAG_REMOVAL |
---|
| 1041 | if( m_layerId > 0 && !m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) ) |
---|
| 1042 | #else |
---|
[540] | 1043 | if( m_layerId > 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) ) |
---|
[906] | 1044 | #endif |
---|
[540] | 1045 | { |
---|
| 1046 | m_pcEncTop->getSPS()->setInferScalingListFlag( true ); |
---|
| 1047 | m_pcEncTop->getSPS()->setScalingListRefLayerId( refLayerId ); |
---|
| 1048 | m_pcEncTop->getSPS()->setScalingListPresentFlag( false ); |
---|
| 1049 | m_pcEncTop->getPPS()->setInferScalingListFlag( false ); |
---|
| 1050 | m_pcEncTop->getPPS()->setScalingListPresentFlag( false ); |
---|
| 1051 | |
---|
| 1052 | // infer the scaling list from the reference layer |
---|
| 1053 | pcSlice->setScalingList ( m_ppcTEncTop[refLayerId]->getScalingList() ); |
---|
| 1054 | } |
---|
| 1055 | else |
---|
| 1056 | { |
---|
[442] | 1057 | #endif |
---|
[540] | 1058 | pcSlice->setDefaultScalingList (); |
---|
| 1059 | m_pcEncTop->getSPS()->setScalingListPresentFlag(false); |
---|
| 1060 | m_pcEncTop->getPPS()->setScalingListPresentFlag(false); |
---|
[442] | 1061 | |
---|
[540] | 1062 | #if SCALINGLIST_INFERRING |
---|
| 1063 | } |
---|
[442] | 1064 | #endif |
---|
| 1065 | |
---|
[313] | 1066 | m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList()); |
---|
| 1067 | m_pcEncTop->getTrQuant()->setUseScalingList(true); |
---|
| 1068 | } |
---|
| 1069 | else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_FILE_READ) |
---|
| 1070 | { |
---|
[540] | 1071 | #if SCALINGLIST_INFERRING |
---|
| 1072 | // inferring of the scaling list can be moved to the config file |
---|
| 1073 | UInt refLayerId = 0; |
---|
[906] | 1074 | #if VPS_AVC_BL_FLAG_REMOVAL |
---|
| 1075 | if( m_layerId > 0 && !m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) ) |
---|
| 1076 | #else |
---|
[540] | 1077 | if( m_layerId > 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) ) |
---|
[906] | 1078 | #endif |
---|
[540] | 1079 | { |
---|
| 1080 | m_pcEncTop->getSPS()->setInferScalingListFlag( true ); |
---|
| 1081 | m_pcEncTop->getSPS()->setScalingListRefLayerId( refLayerId ); |
---|
| 1082 | m_pcEncTop->getSPS()->setScalingListPresentFlag( false ); |
---|
| 1083 | m_pcEncTop->getPPS()->setInferScalingListFlag( false ); |
---|
| 1084 | m_pcEncTop->getPPS()->setScalingListPresentFlag( false ); |
---|
| 1085 | |
---|
| 1086 | // infer the scaling list from the reference layer |
---|
| 1087 | pcSlice->setScalingList ( m_ppcTEncTop[refLayerId]->getScalingList() ); |
---|
| 1088 | } |
---|
| 1089 | else |
---|
| 1090 | { |
---|
[442] | 1091 | #endif |
---|
| 1092 | |
---|
[313] | 1093 | if(pcSlice->getScalingList()->xParseScalingList(m_pcCfg->getScalingListFile())) |
---|
| 1094 | { |
---|
| 1095 | pcSlice->setDefaultScalingList (); |
---|
| 1096 | } |
---|
| 1097 | pcSlice->getScalingList()->checkDcOfMatrix(); |
---|
| 1098 | m_pcEncTop->getSPS()->setScalingListPresentFlag(pcSlice->checkDefaultScalingList()); |
---|
| 1099 | m_pcEncTop->getPPS()->setScalingListPresentFlag(false); |
---|
[442] | 1100 | |
---|
[540] | 1101 | #if SCALINGLIST_INFERRING |
---|
| 1102 | } |
---|
[442] | 1103 | #endif |
---|
| 1104 | |
---|
[313] | 1105 | m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList()); |
---|
| 1106 | m_pcEncTop->getTrQuant()->setUseScalingList(true); |
---|
| 1107 | } |
---|
| 1108 | else |
---|
| 1109 | { |
---|
| 1110 | printf("error : ScalingList == %d no support\n",m_pcEncTop->getUseScalingListId()); |
---|
| 1111 | assert(0); |
---|
| 1112 | } |
---|
| 1113 | |
---|
| 1114 | if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P') |
---|
| 1115 | { |
---|
| 1116 | pcSlice->setSliceType(P_SLICE); |
---|
| 1117 | } |
---|
[595] | 1118 | if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='I') |
---|
| 1119 | { |
---|
| 1120 | pcSlice->setSliceType(I_SLICE); |
---|
| 1121 | } |
---|
| 1122 | |
---|
[313] | 1123 | // Set the nal unit type |
---|
[595] | 1124 | pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField)); |
---|
[313] | 1125 | #if SVC_EXTENSION |
---|
[494] | 1126 | if (m_layerId > 0) |
---|
| 1127 | { |
---|
[815] | 1128 | Int interLayerPredLayerIdcTmp[MAX_VPS_LAYER_ID_PLUS1]; |
---|
| 1129 | Int activeNumILRRefIdxTmp = 0; |
---|
[494] | 1130 | |
---|
[313] | 1131 | for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ ) |
---|
| 1132 | { |
---|
| 1133 | UInt refLayerIdc = pcSlice->getInterLayerPredLayerIdc(i); |
---|
[815] | 1134 | UInt refLayerId = pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc); |
---|
[313] | 1135 | #if VPS_EXTN_DIRECT_REF_LAYERS |
---|
| 1136 | TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId]->getRefLayerEnc(refLayerIdc)->getListPic(); |
---|
| 1137 | #else |
---|
| 1138 | TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId-1]->getListPic(); |
---|
| 1139 | #endif |
---|
| 1140 | pcSlice->setBaseColPic( *cListPic, refLayerIdc ); |
---|
| 1141 | |
---|
[442] | 1142 | // Apply temporal layer restriction to inter-layer prediction |
---|
[494] | 1143 | #if O0225_MAX_TID_FOR_REF_LAYERS |
---|
| 1144 | Int maxTidIlRefPicsPlus1 = m_pcEncTop->getVPS()->getMaxTidIlRefPicsPlus1(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getLayerId(),m_layerId); |
---|
| 1145 | #else |
---|
[442] | 1146 | Int maxTidIlRefPicsPlus1 = m_pcEncTop->getVPS()->getMaxTidIlRefPicsPlus1(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getLayerId()); |
---|
[494] | 1147 | #endif |
---|
[442] | 1148 | if( ((Int)(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getTLayer())<=maxTidIlRefPicsPlus1-1) || (maxTidIlRefPicsPlus1==0 && pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getRapPicFlag()) ) |
---|
| 1149 | { |
---|
| 1150 | interLayerPredLayerIdcTmp[activeNumILRRefIdxTmp++] = refLayerIdc; // add picture to the list of valid inter-layer pictures |
---|
| 1151 | } |
---|
| 1152 | else |
---|
| 1153 | { |
---|
| 1154 | continue; // ILP is not valid due to temporal layer restriction |
---|
| 1155 | } |
---|
| 1156 | |
---|
[540] | 1157 | #if O0098_SCALED_REF_LAYER_ID |
---|
[815] | 1158 | const Window &scalEL = m_pcEncTop->getScaledRefLayerWindowForLayer(refLayerId); |
---|
[540] | 1159 | #else |
---|
[313] | 1160 | const Window &scalEL = m_pcEncTop->getScaledRefLayerWindow(refLayerIdc); |
---|
[540] | 1161 | #endif |
---|
[313] | 1162 | |
---|
[906] | 1163 | #if REF_REGION_OFFSET |
---|
| 1164 | const Window &windowRL = m_pcEncTop->getRefLayerWindowForLayer(pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc)); |
---|
| 1165 | Int widthBL = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getWidth() - windowRL.getWindowLeftOffset() - windowRL.getWindowRightOffset(); |
---|
| 1166 | Int heightBL = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getHeight() - windowRL.getWindowTopOffset() - windowRL.getWindowBottomOffset(); |
---|
| 1167 | #else |
---|
[313] | 1168 | Int widthBL = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getWidth(); |
---|
| 1169 | Int heightBL = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getHeight(); |
---|
[713] | 1170 | #if Q0200_CONFORMANCE_BL_SIZE |
---|
| 1171 | Int chromaFormatIdc = pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getChromaFormatIdc(); |
---|
| 1172 | const Window &confBL = pcSlice->getBaseColPic(refLayerIdc)->getConformanceWindow(); |
---|
| 1173 | widthBL -= ( confBL.getWindowLeftOffset() + confBL.getWindowRightOffset() ) * TComSPS::getWinUnitX( chromaFormatIdc ); |
---|
| 1174 | heightBL -= ( confBL.getWindowTopOffset() + confBL.getWindowBottomOffset() ) * TComSPS::getWinUnitY( chromaFormatIdc ); |
---|
| 1175 | #endif |
---|
[906] | 1176 | #endif |
---|
[313] | 1177 | Int widthEL = pcPic->getPicYuvRec()->getWidth() - scalEL.getWindowLeftOffset() - scalEL.getWindowRightOffset(); |
---|
| 1178 | Int heightEL = pcPic->getPicYuvRec()->getHeight() - scalEL.getWindowTopOffset() - scalEL.getWindowBottomOffset(); |
---|
| 1179 | |
---|
[906] | 1180 | #if RESAMPLING_FIX |
---|
| 1181 | #if REF_REGION_OFFSET |
---|
| 1182 | // conformance check: the values of RefLayerRegionWidthInSamplesY, RefLayerRegionHeightInSamplesY, ScaledRefRegionWidthInSamplesY and ScaledRefRegionHeightInSamplesY shall be greater than 0 |
---|
| 1183 | assert(widthEL > 0 && heightEL > 0 && widthBL > 0 && widthEL > 0); |
---|
| 1184 | |
---|
| 1185 | // conformance check: ScaledRefRegionWidthInSamplesY shall be greater or equal to RefLayerRegionWidthInSamplesY and ScaledRefRegionHeightInSamplesY shall be greater or equal to RefLayerRegionHeightInSamplesY |
---|
| 1186 | assert(widthEL >= widthBL && heightEL >= heightBL); |
---|
| 1187 | |
---|
| 1188 | #if R0209_GENERIC_PHASE |
---|
| 1189 | // conformance check: when ScaledRefRegionWidthInSamplesY is equal to RefLayerRegionWidthInSamplesY, PhaseHorY shall be equal to 0, when ScaledRefRegionWidthInSamplesC is equal to RefLayerRegionWidthInSamplesC, PhaseHorC shall be equal to 0, when ScaledRefRegionHeightInSamplesY is equal to RefLayerRegionHeightInSamplesY, PhaseVerY shall be equal to 0, and when ScaledRefRegionHeightInSamplesC is equal to RefLayerRegionHeightInSamplesC, PhaseVerC shall be equal to 0. |
---|
| 1190 | Int phaseHorLuma = pcSlice->getPPS()->getPhaseHorLuma(refLayerIdc); |
---|
| 1191 | Int phaseVerLuma = pcSlice->getPPS()->getPhaseVerLuma(refLayerIdc); |
---|
| 1192 | Int phaseHorChroma = pcSlice->getPPS()->getPhaseHorChroma(refLayerIdc); |
---|
| 1193 | Int phaseVerChroma = pcSlice->getPPS()->getPhaseVerChroma(refLayerIdc); |
---|
| 1194 | assert( ( (widthEL != widthBL) || (phaseHorLuma == 0 && phaseHorChroma == 0) ) |
---|
| 1195 | && ( (heightEL != heightBL) || (phaseVerLuma == 0 && phaseVerChroma == 0) ) ); |
---|
| 1196 | #endif |
---|
| 1197 | #endif |
---|
| 1198 | #endif |
---|
| 1199 | |
---|
[313] | 1200 | g_mvScalingFactor[refLayerIdc][0] = widthEL == widthBL ? 4096 : Clip3(-4096, 4095, ((widthEL << 8) + (widthBL >> 1)) / widthBL); |
---|
| 1201 | g_mvScalingFactor[refLayerIdc][1] = heightEL == heightBL ? 4096 : Clip3(-4096, 4095, ((heightEL << 8) + (heightBL >> 1)) / heightBL); |
---|
| 1202 | |
---|
| 1203 | g_posScalingFactor[refLayerIdc][0] = ((widthBL << 16) + (widthEL >> 1)) / widthEL; |
---|
| 1204 | g_posScalingFactor[refLayerIdc][1] = ((heightBL << 16) + (heightEL >> 1)) / heightEL; |
---|
| 1205 | |
---|
[713] | 1206 | #if Q0048_CGS_3D_ASYMLUT |
---|
| 1207 | TComPicYuv* pBaseColRec = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(); |
---|
| 1208 | if( pcSlice->getPPS()->getCGSFlag() ) |
---|
| 1209 | { |
---|
[906] | 1210 | #if R0150_CGS_SIGNAL_CONSTRAINTS |
---|
| 1211 | // all reference layers are currently taken as CGS reference layers |
---|
| 1212 | m_Enc3DAsymLUTPPS.addRefLayerId( pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc) ); |
---|
| 1213 | m_Enc3DAsymLUTPicUpdate.addRefLayerId( pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc) ); |
---|
| 1214 | #endif |
---|
[713] | 1215 | if(g_posScalingFactor[refLayerIdc][0] < (1<<16) || g_posScalingFactor[refLayerIdc][1] < (1<<16)) //if(pcPic->isSpatialEnhLayer(refLayerIdc)) |
---|
| 1216 | { |
---|
| 1217 | //downsampling; |
---|
| 1218 | downScalePic(pcPic->getPicYuvOrg(), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg()); |
---|
| 1219 | //pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg()->dump("ds.yuv", true, true); |
---|
| 1220 | m_Enc3DAsymLUTPPS.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg()); |
---|
| 1221 | m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg()); |
---|
| 1222 | } |
---|
| 1223 | else |
---|
| 1224 | { |
---|
| 1225 | m_Enc3DAsymLUTPPS.setDsOrigPic(pcPic->getPicYuvOrg()); |
---|
| 1226 | m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcPic->getPicYuvOrg()); |
---|
| 1227 | } |
---|
| 1228 | |
---|
| 1229 | Bool bSignalPPS = m_bSeqFirst; |
---|
| 1230 | bSignalPPS |= m_pcCfg->getGOPSize() > 1 ? pocCurr % m_pcCfg->getIntraPeriod() == 0 : pocCurr % m_pcCfg->getFrameRate() == 0; |
---|
| 1231 | xDetermin3DAsymLUT( pcSlice , pcPic , refLayerIdc , m_pcCfg , bSignalPPS ); |
---|
| 1232 | m_Enc3DAsymLUTPPS.colorMapping( pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), m_pColorMappedPic ); |
---|
| 1233 | pBaseColRec = m_pColorMappedPic; |
---|
| 1234 | } |
---|
| 1235 | #endif |
---|
[815] | 1236 | #if SVC_EXTENSION |
---|
| 1237 | if( pcPic->isSpatialEnhLayer(refLayerIdc) ) |
---|
[442] | 1238 | { |
---|
[815] | 1239 | // check for the sample prediction picture type |
---|
| 1240 | if( m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag(refLayerId) ) |
---|
| 1241 | { |
---|
[644] | 1242 | #if P0312_VERT_PHASE_ADJ |
---|
[815] | 1243 | //when PhasePositionEnableFlag is equal to 1, set vertPhasePositionFlag to 0 if BL is top field and 1 if bottom |
---|
| 1244 | if( scalEL.getVertPhasePositionEnableFlag() ) |
---|
| 1245 | { |
---|
| 1246 | pcSlice->setVertPhasePositionFlag( pcSlice->getPOC()%2, refLayerIdc ); |
---|
| 1247 | } |
---|
[644] | 1248 | #endif |
---|
[494] | 1249 | #if O0215_PHASE_ALIGNMENT |
---|
| 1250 | #if O0194_JOINT_US_BITSHIFT |
---|
[713] | 1251 | #if Q0048_CGS_3D_ASYMLUT |
---|
[815] | 1252 | m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), pcSlice->getVPS()->getPhaseAlignFlag() ); |
---|
[313] | 1253 | #else |
---|
[815] | 1254 | m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), pcSlice->getVPS()->getPhaseAlignFlag() ); |
---|
[713] | 1255 | #endif |
---|
| 1256 | #else |
---|
| 1257 | #if Q0048_CGS_3D_ASYMLUT |
---|
[815] | 1258 | m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() ); |
---|
[713] | 1259 | #else |
---|
[815] | 1260 | m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() ); |
---|
[313] | 1261 | #endif |
---|
[713] | 1262 | #endif |
---|
[494] | 1263 | #else |
---|
| 1264 | #if O0194_JOINT_US_BITSHIFT |
---|
[713] | 1265 | #if Q0048_CGS_3D_ASYMLUT |
---|
[906] | 1266 | #if REF_REGION_OFFSET |
---|
| 1267 | m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL, altRL ); |
---|
[713] | 1268 | #else |
---|
[906] | 1269 | m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL ); |
---|
[713] | 1270 | #endif |
---|
[494] | 1271 | #else |
---|
[906] | 1272 | m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL ); |
---|
| 1273 | #endif |
---|
| 1274 | #else |
---|
[713] | 1275 | #if Q0048_CGS_3D_ASYMLUT |
---|
[815] | 1276 | m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL ); |
---|
[713] | 1277 | #else |
---|
[815] | 1278 | m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL ); |
---|
[494] | 1279 | #endif |
---|
| 1280 | #endif |
---|
[713] | 1281 | #endif |
---|
[815] | 1282 | } |
---|
[313] | 1283 | } |
---|
| 1284 | else |
---|
| 1285 | { |
---|
[713] | 1286 | #if Q0048_CGS_3D_ASYMLUT |
---|
| 1287 | pcPic->setFullPelBaseRec( refLayerIdc, pBaseColRec ); |
---|
| 1288 | #else |
---|
[313] | 1289 | pcPic->setFullPelBaseRec( refLayerIdc, pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec() ); |
---|
[713] | 1290 | #endif |
---|
[313] | 1291 | } |
---|
| 1292 | pcSlice->setFullPelBaseRec ( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc) ); |
---|
[815] | 1293 | #endif //SVC_EXTENSION |
---|
[313] | 1294 | } |
---|
| 1295 | |
---|
[442] | 1296 | // Update the list of active inter-layer pictures |
---|
| 1297 | for ( Int i = 0; i < activeNumILRRefIdxTmp; i++) |
---|
[313] | 1298 | { |
---|
[442] | 1299 | pcSlice->setInterLayerPredLayerIdc( interLayerPredLayerIdcTmp[i], i ); |
---|
[313] | 1300 | } |
---|
[540] | 1301 | |
---|
[713] | 1302 | #if !O0225_TID_BASED_IL_RPS_DERIV || Q0060_MAX_TID_REF_EQUAL_TO_ZERO |
---|
[442] | 1303 | pcSlice->setActiveNumILRRefIdx( activeNumILRRefIdxTmp ); |
---|
[540] | 1304 | #endif |
---|
[442] | 1305 | if ( pcSlice->getActiveNumILRRefIdx() == 0 ) |
---|
| 1306 | { |
---|
| 1307 | // No valid inter-layer pictures -> disable inter-layer prediction |
---|
| 1308 | pcSlice->setInterLayerPredEnabledFlag(false); |
---|
| 1309 | } |
---|
[815] | 1310 | |
---|
[442] | 1311 | if( pocCurr % m_pcCfg->getIntraPeriod() == 0 ) |
---|
| 1312 | { |
---|
| 1313 | if(pcSlice->getVPS()->getCrossLayerIrapAlignFlag()) |
---|
| 1314 | { |
---|
| 1315 | TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId]->getRefLayerEnc(0)->getListPic(); |
---|
| 1316 | TComPic* picLayer0 = pcSlice->getRefPic(*cListPic, pcSlice->getPOC() ); |
---|
| 1317 | if(picLayer0) |
---|
| 1318 | { |
---|
| 1319 | pcSlice->setNalUnitType(picLayer0->getSlice(0)->getNalUnitType()); |
---|
| 1320 | } |
---|
| 1321 | else |
---|
| 1322 | { |
---|
| 1323 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_CRA); |
---|
| 1324 | } |
---|
| 1325 | } |
---|
| 1326 | else |
---|
| 1327 | { |
---|
[815] | 1328 | #if !ALIGN_IRAP_BUGFIX |
---|
[442] | 1329 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_CRA); |
---|
[815] | 1330 | #endif |
---|
[442] | 1331 | } |
---|
| 1332 | } |
---|
[906] | 1333 | #if ISLICE_TYPE_NUMDIR |
---|
| 1334 | if( pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA && (m_pcEncTop->getNumDirectRefLayers() == 0) ) |
---|
| 1335 | #else |
---|
[442] | 1336 | if( pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA ) |
---|
[906] | 1337 | #endif |
---|
[313] | 1338 | { |
---|
[442] | 1339 | pcSlice->setSliceType(I_SLICE); |
---|
[313] | 1340 | } |
---|
[442] | 1341 | else if( !m_pcEncTop->getElRapSliceTypeB() ) |
---|
| 1342 | { |
---|
| 1343 | if( (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP) && |
---|
[815] | 1344 | (pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA) && |
---|
| 1345 | pcSlice->getSliceType() == B_SLICE ) |
---|
[442] | 1346 | { |
---|
| 1347 | pcSlice->setSliceType(P_SLICE); |
---|
| 1348 | } |
---|
[815] | 1349 | } |
---|
[313] | 1350 | } |
---|
[442] | 1351 | #endif //#if SVC_EXTENSION |
---|
[313] | 1352 | if(pcSlice->getTemporalLayerNonReferenceFlag()) |
---|
| 1353 | { |
---|
[442] | 1354 | if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_TRAIL_R && |
---|
[815] | 1355 | #if SVC_EXTENSION |
---|
| 1356 | ( m_iGopSize != 1 || m_ppcTEncTop[m_layerId]->getIntraPeriod() > 1 ) ) |
---|
| 1357 | #else |
---|
[442] | 1358 | !(m_iGopSize == 1 && pcSlice->getSliceType() == I_SLICE)) |
---|
[815] | 1359 | #endif |
---|
[442] | 1360 | // Add this condition to avoid POC issues with encoder_intra_main.cfg configuration (see #1127 in bug tracker) |
---|
[313] | 1361 | { |
---|
| 1362 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TRAIL_N); |
---|
| 1363 | } |
---|
| 1364 | if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RADL_R) |
---|
| 1365 | { |
---|
| 1366 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RADL_N); |
---|
| 1367 | } |
---|
| 1368 | if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RASL_R) |
---|
| 1369 | { |
---|
| 1370 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RASL_N); |
---|
| 1371 | } |
---|
| 1372 | } |
---|
| 1373 | |
---|
[713] | 1374 | #if EFFICIENT_FIELD_IRAP |
---|
| 1375 | #if FIX1172 |
---|
| 1376 | if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP |
---|
| 1377 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL |
---|
| 1378 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP |
---|
| 1379 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL |
---|
| 1380 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP |
---|
| 1381 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) // IRAP picture |
---|
| 1382 | { |
---|
| 1383 | m_associatedIRAPType = pcSlice->getNalUnitType(); |
---|
[815] | 1384 | #if POC_RESET_IDC_ENCODER |
---|
| 1385 | m_associatedIRAPPOC = pcSlice->getPOC(); |
---|
| 1386 | m_associatedIrapPocBeforeReset = pocCurr; |
---|
| 1387 | #else |
---|
[713] | 1388 | m_associatedIRAPPOC = pocCurr; |
---|
[815] | 1389 | #endif |
---|
[713] | 1390 | } |
---|
| 1391 | pcSlice->setAssociatedIRAPType(m_associatedIRAPType); |
---|
| 1392 | pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC); |
---|
[815] | 1393 | #if POC_RESET_IDC_ENCODER |
---|
| 1394 | pcSlice->setAssociatedIrapPocBeforeReset(m_associatedIrapPocBeforeReset); |
---|
[713] | 1395 | #endif |
---|
| 1396 | #endif |
---|
[815] | 1397 | #endif |
---|
[313] | 1398 | // Do decoding refresh marking if any |
---|
[540] | 1399 | #if NO_CLRAS_OUTPUT_FLAG |
---|
| 1400 | pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcEncTop->getNoClrasOutputFlag()); |
---|
| 1401 | #else |
---|
[313] | 1402 | pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic); |
---|
[540] | 1403 | #endif |
---|
[815] | 1404 | #if POC_RESET_IDC_ENCODER |
---|
| 1405 | // m_pocCRA may have been update here; update m_pocCraWithoutReset |
---|
| 1406 | m_pocCraWithoutReset = m_pocCRA + m_pcEncTop->getPocAdjustmentValue(); |
---|
| 1407 | #endif |
---|
[313] | 1408 | m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid); |
---|
| 1409 | pcSlice->getRPS()->setNumberOfLongtermPictures(0); |
---|
[713] | 1410 | #if EFFICIENT_FIELD_IRAP |
---|
| 1411 | #else |
---|
[595] | 1412 | #if FIX1172 |
---|
| 1413 | if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP |
---|
| 1414 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL |
---|
| 1415 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP |
---|
| 1416 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL |
---|
| 1417 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP |
---|
| 1418 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA ) // IRAP picture |
---|
| 1419 | { |
---|
| 1420 | m_associatedIRAPType = pcSlice->getNalUnitType(); |
---|
| 1421 | m_associatedIRAPPOC = pocCurr; |
---|
| 1422 | } |
---|
| 1423 | pcSlice->setAssociatedIRAPType(m_associatedIRAPType); |
---|
| 1424 | pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC); |
---|
| 1425 | #endif |
---|
[713] | 1426 | #endif |
---|
[313] | 1427 | |
---|
[713] | 1428 | #if ALLOW_RECOVERY_POINT_AS_RAP |
---|
| 1429 | if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP()) |
---|
| 1430 | #if EFFICIENT_FIELD_IRAP |
---|
| 1431 | || (isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1) |
---|
| 1432 | #endif |
---|
| 1433 | ) |
---|
| 1434 | { |
---|
| 1435 | pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3); |
---|
| 1436 | } |
---|
| 1437 | #else |
---|
[313] | 1438 | if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false) != 0) || (pcSlice->isIRAP())) |
---|
| 1439 | { |
---|
| 1440 | pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP()); |
---|
| 1441 | } |
---|
[713] | 1442 | #endif |
---|
[644] | 1443 | #if ALIGNED_BUMPING |
---|
[815] | 1444 | #if POC_RESET_IDC_ENCODER |
---|
| 1445 | pcSlice->checkLeadingPictureRestrictions(rcListPic, true); |
---|
| 1446 | #else |
---|
[644] | 1447 | pcSlice->checkLeadingPictureRestrictions(rcListPic); |
---|
| 1448 | #endif |
---|
[815] | 1449 | #endif |
---|
[313] | 1450 | pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS()); |
---|
| 1451 | |
---|
[595] | 1452 | if(pcSlice->getTLayer() > 0 |
---|
| 1453 | && !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N // Check if not a leading picture |
---|
| 1454 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R |
---|
| 1455 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N |
---|
| 1456 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R ) |
---|
| 1457 | ) |
---|
[313] | 1458 | { |
---|
| 1459 | if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic) || pcSlice->getSPS()->getTemporalIdNestingFlag()) |
---|
| 1460 | { |
---|
[906] | 1461 | #if SVC_EXTENSION && !Q0108_TSA_STSA |
---|
[442] | 1462 | if( pcSlice->getLayerId() > 0 ) |
---|
| 1463 | { |
---|
| 1464 | Bool oneRefLayerTSA = false, oneRefLayerNotTSA = false; |
---|
| 1465 | for( Int i = 0; i < pcSlice->getLayerId(); i++) |
---|
| 1466 | { |
---|
| 1467 | TComList<TComPic *> *cListPic = m_ppcTEncTop[i]->getListPic(); |
---|
| 1468 | TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC()); |
---|
| 1469 | if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerId(), i) ) |
---|
| 1470 | { |
---|
| 1471 | if( ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_TSA_N ) || |
---|
[540] | 1472 | ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_TSA_R ) |
---|
[442] | 1473 | ) |
---|
| 1474 | { |
---|
| 1475 | if(pcSlice->getTemporalLayerNonReferenceFlag() ) |
---|
| 1476 | { |
---|
| 1477 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N); |
---|
| 1478 | } |
---|
| 1479 | else |
---|
| 1480 | { |
---|
[540] | 1481 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R ); |
---|
[442] | 1482 | } |
---|
| 1483 | oneRefLayerTSA = true; |
---|
| 1484 | } |
---|
| 1485 | else |
---|
| 1486 | { |
---|
| 1487 | oneRefLayerNotTSA = true; |
---|
| 1488 | } |
---|
| 1489 | } |
---|
| 1490 | } |
---|
| 1491 | assert( !( oneRefLayerNotTSA && oneRefLayerTSA ) ); // Only one variable should be true - failure of this assert means |
---|
| 1492 | // that two independent reference layers that are not dependent on |
---|
| 1493 | // each other, but are reference for current layer have inconsistency |
---|
| 1494 | if( oneRefLayerNotTSA /*&& !oneRefLayerTSA*/ ) // No reference layer is TSA - set current as TRAIL |
---|
| 1495 | { |
---|
| 1496 | if(pcSlice->getTemporalLayerNonReferenceFlag() ) |
---|
| 1497 | { |
---|
| 1498 | pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_N ); |
---|
| 1499 | } |
---|
| 1500 | else |
---|
| 1501 | { |
---|
| 1502 | pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_R ); |
---|
| 1503 | } |
---|
| 1504 | } |
---|
| 1505 | else // This means there is no reference layer picture for current picture in this AU |
---|
| 1506 | { |
---|
| 1507 | if(pcSlice->getTemporalLayerNonReferenceFlag() ) |
---|
| 1508 | { |
---|
| 1509 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N); |
---|
| 1510 | } |
---|
| 1511 | else |
---|
| 1512 | { |
---|
[540] | 1513 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R ); |
---|
[442] | 1514 | } |
---|
| 1515 | } |
---|
| 1516 | } |
---|
| 1517 | #else |
---|
[313] | 1518 | if(pcSlice->getTemporalLayerNonReferenceFlag()) |
---|
| 1519 | { |
---|
| 1520 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N); |
---|
| 1521 | } |
---|
| 1522 | else |
---|
| 1523 | { |
---|
[540] | 1524 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R); |
---|
[313] | 1525 | } |
---|
[442] | 1526 | #endif |
---|
[313] | 1527 | } |
---|
| 1528 | else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic)) |
---|
| 1529 | { |
---|
| 1530 | Bool isSTSA=true; |
---|
| 1531 | for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++) |
---|
| 1532 | { |
---|
| 1533 | Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId; |
---|
| 1534 | if(lTid==pcSlice->getTLayer()) |
---|
| 1535 | { |
---|
| 1536 | TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii); |
---|
| 1537 | for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++) |
---|
| 1538 | { |
---|
| 1539 | if(nRPS->getUsed(jj)) |
---|
| 1540 | { |
---|
| 1541 | Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj); |
---|
| 1542 | Int kk=0; |
---|
| 1543 | for(kk=0;kk<m_pcCfg->getGOPSize();kk++) |
---|
| 1544 | { |
---|
| 1545 | if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc) |
---|
| 1546 | break; |
---|
| 1547 | } |
---|
| 1548 | Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId; |
---|
| 1549 | if(tTid >= pcSlice->getTLayer()) |
---|
| 1550 | { |
---|
| 1551 | isSTSA=false; |
---|
| 1552 | break; |
---|
| 1553 | } |
---|
| 1554 | } |
---|
| 1555 | } |
---|
| 1556 | } |
---|
| 1557 | } |
---|
| 1558 | if(isSTSA==true) |
---|
| 1559 | { |
---|
[906] | 1560 | #if SVC_EXTENSION && !Q0108_TSA_STSA |
---|
[442] | 1561 | if( pcSlice->getLayerId() > 0 ) |
---|
| 1562 | { |
---|
| 1563 | Bool oneRefLayerSTSA = false, oneRefLayerNotSTSA = false; |
---|
| 1564 | for( Int i = 0; i < pcSlice->getLayerId(); i++) |
---|
| 1565 | { |
---|
| 1566 | TComList<TComPic *> *cListPic = m_ppcTEncTop[i]->getListPic(); |
---|
| 1567 | TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC()); |
---|
| 1568 | if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerId(), i) ) |
---|
| 1569 | { |
---|
| 1570 | if( ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_STSA_N ) || |
---|
| 1571 | ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_STSA_R ) |
---|
| 1572 | ) |
---|
| 1573 | { |
---|
| 1574 | if(pcSlice->getTemporalLayerNonReferenceFlag() ) |
---|
| 1575 | { |
---|
| 1576 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N); |
---|
| 1577 | } |
---|
| 1578 | else |
---|
| 1579 | { |
---|
| 1580 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R ); |
---|
| 1581 | } |
---|
| 1582 | oneRefLayerSTSA = true; |
---|
| 1583 | } |
---|
| 1584 | else |
---|
| 1585 | { |
---|
| 1586 | oneRefLayerNotSTSA = true; |
---|
| 1587 | } |
---|
| 1588 | } |
---|
| 1589 | } |
---|
| 1590 | assert( !( oneRefLayerNotSTSA && oneRefLayerSTSA ) ); // Only one variable should be true - failure of this assert means |
---|
| 1591 | // that two independent reference layers that are not dependent on |
---|
| 1592 | // each other, but are reference for current layer have inconsistency |
---|
| 1593 | if( oneRefLayerNotSTSA /*&& !oneRefLayerSTSA*/ ) // No reference layer is STSA - set current as TRAIL |
---|
| 1594 | { |
---|
| 1595 | if(pcSlice->getTemporalLayerNonReferenceFlag() ) |
---|
| 1596 | { |
---|
| 1597 | pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_N ); |
---|
| 1598 | } |
---|
| 1599 | else |
---|
| 1600 | { |
---|
| 1601 | pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_R ); |
---|
| 1602 | } |
---|
| 1603 | } |
---|
| 1604 | else // This means there is no reference layer picture for current picture in this AU |
---|
| 1605 | { |
---|
| 1606 | if(pcSlice->getTemporalLayerNonReferenceFlag() ) |
---|
| 1607 | { |
---|
| 1608 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N); |
---|
| 1609 | } |
---|
| 1610 | else |
---|
| 1611 | { |
---|
| 1612 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R ); |
---|
| 1613 | } |
---|
| 1614 | } |
---|
| 1615 | } |
---|
| 1616 | #else |
---|
[313] | 1617 | if(pcSlice->getTemporalLayerNonReferenceFlag()) |
---|
| 1618 | { |
---|
| 1619 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N); |
---|
| 1620 | } |
---|
| 1621 | else |
---|
| 1622 | { |
---|
| 1623 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R); |
---|
| 1624 | } |
---|
[442] | 1625 | #endif |
---|
[313] | 1626 | } |
---|
| 1627 | } |
---|
| 1628 | } |
---|
[815] | 1629 | |
---|
[313] | 1630 | arrangeLongtermPicturesInRPS(pcSlice, rcListPic); |
---|
| 1631 | TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification(); |
---|
| 1632 | refPicListModification->setRefPicListModificationFlagL0(0); |
---|
| 1633 | refPicListModification->setRefPicListModificationFlagL1(0); |
---|
| 1634 | pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures())); |
---|
| 1635 | pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures())); |
---|
| 1636 | |
---|
[442] | 1637 | #if SVC_EXTENSION |
---|
[313] | 1638 | if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() ) |
---|
| 1639 | { |
---|
[815] | 1640 | #if POC_RESET_FLAG || POC_RESET_IDC_ENCODER |
---|
| 1641 | if ( pocCurr > 0 && pcSlice->isRADL() && pcPic->getSlice(0)->getBaseColPic(pcPic->getSlice(0)->getInterLayerPredLayerIdc(0))->getSlice(0)->isRASL()) |
---|
[442] | 1642 | #else |
---|
| 1643 | if (pcSlice->getPOC()>0 && pcSlice->isRADL() && pcPic->getSlice(0)->getBaseColPic(pcPic->getSlice(0)->getInterLayerPredLayerIdc(0))->getSlice(0)->isRASL()) |
---|
| 1644 | #endif |
---|
[313] | 1645 | { |
---|
| 1646 | pcSlice->setActiveNumILRRefIdx(0); |
---|
| 1647 | pcSlice->setInterLayerPredEnabledFlag(0); |
---|
| 1648 | } |
---|
[906] | 1649 | if( pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA ) |
---|
[313] | 1650 | { |
---|
| 1651 | pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getActiveNumILRRefIdx()); |
---|
| 1652 | pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getActiveNumILRRefIdx()); |
---|
| 1653 | } |
---|
| 1654 | else |
---|
| 1655 | { |
---|
| 1656 | pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getNumRefIdx(REF_PIC_LIST_0)+pcSlice->getActiveNumILRRefIdx()); |
---|
| 1657 | pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getNumRefIdx(REF_PIC_LIST_1)+pcSlice->getActiveNumILRRefIdx()); |
---|
| 1658 | } |
---|
[815] | 1659 | |
---|
| 1660 | // check for the reference pictures whether there is at least one either temporal picture or ILRP with sample prediction type |
---|
| 1661 | if( pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) - pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) - pcSlice->getActiveNumILRRefIdx() == 0 ) |
---|
| 1662 | { |
---|
| 1663 | Bool foundSamplePredPicture = false; |
---|
| 1664 | |
---|
| 1665 | for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ ) |
---|
| 1666 | { |
---|
| 1667 | if( m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag( pcSlice->getVPS()->getRefLayerId( m_layerId, pcSlice->getInterLayerPredLayerIdc(i) ) ) ) |
---|
| 1668 | { |
---|
| 1669 | foundSamplePredPicture = true; |
---|
| 1670 | break; |
---|
| 1671 | } |
---|
| 1672 | } |
---|
| 1673 | |
---|
| 1674 | if( !foundSamplePredPicture ) |
---|
| 1675 | { |
---|
| 1676 | pcSlice->setSliceType(I_SLICE); |
---|
| 1677 | pcSlice->setInterLayerPredEnabledFlag(0); |
---|
| 1678 | pcSlice->setActiveNumILRRefIdx(0); |
---|
| 1679 | } |
---|
| 1680 | } |
---|
[313] | 1681 | } |
---|
[442] | 1682 | #endif //SVC_EXTENSION |
---|
[313] | 1683 | |
---|
[906] | 1684 | #if Q0108_TSA_STSA |
---|
| 1685 | if( ( pcSlice->getTLayer() == 0 && pcSlice->getLayerId() > 0 ) // only for enhancement layer and with temporal layer 0 |
---|
| 1686 | && !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N |
---|
| 1687 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R |
---|
| 1688 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N |
---|
| 1689 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R |
---|
| 1690 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL |
---|
| 1691 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP |
---|
| 1692 | || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA |
---|
| 1693 | ) |
---|
| 1694 | ) |
---|
| 1695 | { |
---|
| 1696 | Bool isSTSA=true; |
---|
| 1697 | Bool isIntra=false; |
---|
| 1698 | |
---|
| 1699 | for( Int i = 0; i < pcSlice->getLayerId(); i++) |
---|
| 1700 | { |
---|
| 1701 | TComList<TComPic *> *cListPic = m_ppcTEncTop[i]->getListPic(); |
---|
| 1702 | TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC()); |
---|
| 1703 | if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerId(), i) ) |
---|
| 1704 | { |
---|
| 1705 | if( lowerLayerPic->getSlice(0)->getSliceType() == I_SLICE) |
---|
| 1706 | { |
---|
| 1707 | isIntra = true; |
---|
| 1708 | } |
---|
| 1709 | } |
---|
| 1710 | } |
---|
| 1711 | |
---|
| 1712 | for(Int ii=iGOPid+1; ii < m_pcCfg->getGOPSize() && isSTSA; ii++) |
---|
| 1713 | { |
---|
| 1714 | Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId; |
---|
| 1715 | if(lTid==pcSlice->getTLayer()) |
---|
| 1716 | { |
---|
| 1717 | TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii); |
---|
| 1718 | for(Int jj=0; jj<nRPS->getNumberOfPictures(); jj++) |
---|
| 1719 | { |
---|
| 1720 | if(nRPS->getUsed(jj)) |
---|
| 1721 | { |
---|
| 1722 | Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj); |
---|
| 1723 | Int kk=0; |
---|
| 1724 | for(kk=0; kk<m_pcCfg->getGOPSize(); kk++) |
---|
| 1725 | { |
---|
| 1726 | if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc) |
---|
| 1727 | { |
---|
| 1728 | break; |
---|
| 1729 | } |
---|
| 1730 | } |
---|
| 1731 | Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId; |
---|
| 1732 | if(tTid >= pcSlice->getTLayer()) |
---|
| 1733 | { |
---|
| 1734 | isSTSA = false; |
---|
| 1735 | break; |
---|
| 1736 | } |
---|
| 1737 | } |
---|
| 1738 | } |
---|
| 1739 | } |
---|
| 1740 | } |
---|
| 1741 | if(isSTSA==true && isIntra == false) |
---|
| 1742 | { |
---|
| 1743 | if(pcSlice->getTemporalLayerNonReferenceFlag()) |
---|
| 1744 | { |
---|
| 1745 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N); |
---|
| 1746 | } |
---|
| 1747 | else |
---|
| 1748 | { |
---|
| 1749 | pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R); |
---|
| 1750 | } |
---|
| 1751 | } |
---|
| 1752 | } |
---|
| 1753 | #endif |
---|
| 1754 | |
---|
[313] | 1755 | #if ADAPTIVE_QP_SELECTION |
---|
| 1756 | pcSlice->setTrQuant( m_pcEncTop->getTrQuant() ); |
---|
| 1757 | #endif |
---|
| 1758 | |
---|
[442] | 1759 | #if SVC_EXTENSION |
---|
[313] | 1760 | if( pcSlice->getSliceType() == B_SLICE ) |
---|
| 1761 | { |
---|
| 1762 | pcSlice->setColFromL0Flag(1-uiColDir); |
---|
| 1763 | } |
---|
| 1764 | |
---|
| 1765 | // Set reference list |
---|
| 1766 | if(m_layerId == 0 || ( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() == 0 ) ) |
---|
| 1767 | { |
---|
[906] | 1768 | pcSlice->setRefPicList( rcListPic ); |
---|
[313] | 1769 | } |
---|
[442] | 1770 | |
---|
[313] | 1771 | if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() ) |
---|
| 1772 | { |
---|
[494] | 1773 | pcSlice->setILRPic( m_pcEncTop->getIlpList() ); |
---|
[906] | 1774 | #if !REF_IDX_MFM |
---|
[442] | 1775 | // Set reference list |
---|
| 1776 | pcSlice->setRefPicList ( rcListPic ); |
---|
[815] | 1777 | #endif |
---|
[313] | 1778 | pcSlice->setRefPicListModificationSvc(); |
---|
| 1779 | pcSlice->setRefPicList( rcListPic, false, m_pcEncTop->getIlpList()); |
---|
| 1780 | |
---|
| 1781 | #if REF_IDX_MFM |
---|
[352] | 1782 | if( pcSlice->getMFMEnabledFlag() ) |
---|
[313] | 1783 | { |
---|
| 1784 | Bool found = false; |
---|
| 1785 | UInt ColFromL0Flag = pcSlice->getColFromL0Flag(); |
---|
| 1786 | UInt ColRefIdx = pcSlice->getColRefIdx(); |
---|
[494] | 1787 | |
---|
[313] | 1788 | for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) |
---|
[815] | 1789 | { |
---|
| 1790 | RefPicList refList = RefPicList(1 - ColFromL0Flag); |
---|
| 1791 | TComPic* refPic = pcSlice->getRefPic(refList, colIdx); |
---|
| 1792 | |
---|
| 1793 | // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture, |
---|
| 1794 | // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture. |
---|
| 1795 | if( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getMotionPredEnabledFlag( refPic->getLayerId() ) |
---|
[494] | 1796 | #if MFM_ENCCONSTRAINT |
---|
[815] | 1797 | && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerId()]->getListPic() )->checkSameRefInfo() == true |
---|
[494] | 1798 | #endif |
---|
| 1799 | ) |
---|
[313] | 1800 | { |
---|
| 1801 | ColRefIdx = colIdx; |
---|
| 1802 | found = true; |
---|
| 1803 | break; |
---|
| 1804 | } |
---|
| 1805 | } |
---|
| 1806 | |
---|
| 1807 | if( found == false ) |
---|
| 1808 | { |
---|
| 1809 | ColFromL0Flag = 1 - ColFromL0Flag; |
---|
| 1810 | for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) |
---|
[815] | 1811 | { |
---|
| 1812 | RefPicList refList = RefPicList(1 - ColFromL0Flag); |
---|
| 1813 | TComPic* refPic = pcSlice->getRefPic(refList, colIdx); |
---|
| 1814 | |
---|
| 1815 | // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture, |
---|
| 1816 | // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture. |
---|
| 1817 | if( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getMotionPredEnabledFlag( refPic->getLayerId() ) |
---|
[494] | 1818 | #if MFM_ENCCONSTRAINT |
---|
[815] | 1819 | && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerId()]->getListPic() )->checkSameRefInfo() == true |
---|
[494] | 1820 | #endif |
---|
| 1821 | ) |
---|
[313] | 1822 | { |
---|
| 1823 | ColRefIdx = colIdx; |
---|
| 1824 | found = true; |
---|
| 1825 | break; |
---|
| 1826 | } |
---|
| 1827 | } |
---|
| 1828 | } |
---|
| 1829 | |
---|
| 1830 | if(found == true) |
---|
| 1831 | { |
---|
| 1832 | pcSlice->setColFromL0Flag(ColFromL0Flag); |
---|
| 1833 | pcSlice->setColRefIdx(ColRefIdx); |
---|
| 1834 | } |
---|
| 1835 | } |
---|
| 1836 | #endif |
---|
| 1837 | } |
---|
[442] | 1838 | #else //SVC_EXTENSION |
---|
| 1839 | // Set reference list |
---|
| 1840 | pcSlice->setRefPicList ( rcListPic ); |
---|
| 1841 | #endif //#if SVC_EXTENSION |
---|
[313] | 1842 | |
---|
| 1843 | // Slice info. refinement |
---|
| 1844 | if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) ) |
---|
| 1845 | { |
---|
| 1846 | pcSlice->setSliceType ( P_SLICE ); |
---|
| 1847 | } |
---|
| 1848 | |
---|
| 1849 | if (pcSlice->getSliceType() == B_SLICE) |
---|
| 1850 | { |
---|
[442] | 1851 | #if !SVC_EXTENSION |
---|
[313] | 1852 | pcSlice->setColFromL0Flag(1-uiColDir); |
---|
| 1853 | #endif |
---|
| 1854 | Bool bLowDelay = true; |
---|
| 1855 | Int iCurrPOC = pcSlice->getPOC(); |
---|
| 1856 | Int iRefIdx = 0; |
---|
| 1857 | |
---|
| 1858 | for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++) |
---|
| 1859 | { |
---|
| 1860 | if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC ) |
---|
| 1861 | { |
---|
| 1862 | bLowDelay = false; |
---|
| 1863 | } |
---|
| 1864 | } |
---|
| 1865 | for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++) |
---|
| 1866 | { |
---|
| 1867 | if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC ) |
---|
| 1868 | { |
---|
| 1869 | bLowDelay = false; |
---|
| 1870 | } |
---|
| 1871 | } |
---|
| 1872 | |
---|
| 1873 | pcSlice->setCheckLDC(bLowDelay); |
---|
| 1874 | } |
---|
| 1875 | else |
---|
| 1876 | { |
---|
| 1877 | pcSlice->setCheckLDC(true); |
---|
| 1878 | } |
---|
| 1879 | |
---|
| 1880 | uiColDir = 1-uiColDir; |
---|
| 1881 | |
---|
| 1882 | //------------------------------------------------------------- |
---|
| 1883 | pcSlice->setRefPOCList(); |
---|
| 1884 | |
---|
| 1885 | pcSlice->setList1IdxToList0Idx(); |
---|
| 1886 | |
---|
| 1887 | if (m_pcEncTop->getTMVPModeId() == 2) |
---|
| 1888 | { |
---|
| 1889 | if (iGOPid == 0) // first picture in SOP (i.e. forward B) |
---|
| 1890 | { |
---|
| 1891 | pcSlice->setEnableTMVPFlag(0); |
---|
| 1892 | } |
---|
| 1893 | else |
---|
| 1894 | { |
---|
| 1895 | // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0. |
---|
| 1896 | pcSlice->setEnableTMVPFlag(1); |
---|
| 1897 | } |
---|
| 1898 | pcSlice->getSPS()->setTMVPFlagsPresent(1); |
---|
| 1899 | } |
---|
| 1900 | else if (m_pcEncTop->getTMVPModeId() == 1) |
---|
| 1901 | { |
---|
| 1902 | pcSlice->getSPS()->setTMVPFlagsPresent(1); |
---|
| 1903 | #if SVC_EXTENSION |
---|
| 1904 | if( pcSlice->getIdrPicFlag() ) |
---|
| 1905 | { |
---|
| 1906 | pcSlice->setEnableTMVPFlag(0); |
---|
| 1907 | } |
---|
| 1908 | else |
---|
| 1909 | #endif |
---|
| 1910 | pcSlice->setEnableTMVPFlag(1); |
---|
| 1911 | } |
---|
| 1912 | else |
---|
| 1913 | { |
---|
| 1914 | pcSlice->getSPS()->setTMVPFlagsPresent(0); |
---|
| 1915 | pcSlice->setEnableTMVPFlag(0); |
---|
| 1916 | } |
---|
[815] | 1917 | |
---|
| 1918 | #if SVC_EXTENSION |
---|
| 1919 | if( m_layerId > 0 && !pcSlice->isIntra() ) |
---|
| 1920 | { |
---|
| 1921 | Int colFromL0Flag = 1; |
---|
| 1922 | Int colRefIdx = 0; |
---|
| 1923 | |
---|
| 1924 | // check whether collocated picture is valid |
---|
| 1925 | if( pcSlice->getEnableTMVPFlag() ) |
---|
| 1926 | { |
---|
| 1927 | colFromL0Flag = pcSlice->getColFromL0Flag(); |
---|
| 1928 | colRefIdx = pcSlice->getColRefIdx(); |
---|
| 1929 | |
---|
| 1930 | TComPic* refPic = pcSlice->getRefPic(RefPicList(1-colFromL0Flag), colRefIdx); |
---|
| 1931 | |
---|
| 1932 | assert( refPic ); |
---|
| 1933 | |
---|
| 1934 | // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture, |
---|
| 1935 | // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture. |
---|
| 1936 | if( refPic->isILR(m_layerId) && !m_ppcTEncTop[m_layerId]->getMotionPredEnabledFlag(refPic->getLayerId()) ) |
---|
| 1937 | { |
---|
| 1938 | pcSlice->setEnableTMVPFlag(false); |
---|
| 1939 | pcSlice->setMFMEnabledFlag(false); |
---|
| 1940 | colRefIdx = 0; |
---|
| 1941 | } |
---|
| 1942 | } |
---|
| 1943 | |
---|
| 1944 | // remove motion only ILRP from the end of the colFromL0Flag reference picture list |
---|
| 1945 | RefPicList refList = RefPicList(colFromL0Flag); |
---|
| 1946 | Int numRefIdx = pcSlice->getNumRefIdx(refList); |
---|
| 1947 | |
---|
| 1948 | if( numRefIdx > 0 ) |
---|
| 1949 | { |
---|
| 1950 | for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > 0; refIdx-- ) |
---|
| 1951 | { |
---|
| 1952 | TComPic* refPic = pcSlice->getRefPic(refList, refIdx); |
---|
| 1953 | |
---|
| 1954 | if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag( refPic->getLayerId() ) ) ) |
---|
| 1955 | { |
---|
| 1956 | break; |
---|
| 1957 | } |
---|
| 1958 | else |
---|
| 1959 | { |
---|
| 1960 | assert( numRefIdx > 1 ); |
---|
| 1961 | numRefIdx--; |
---|
| 1962 | } |
---|
| 1963 | } |
---|
| 1964 | |
---|
| 1965 | pcSlice->setNumRefIdx( refList, numRefIdx ); |
---|
| 1966 | } |
---|
| 1967 | |
---|
| 1968 | // remove motion only ILRP from the end of the (1-colFromL0Flag) reference picture list up to colRefIdx |
---|
| 1969 | refList = RefPicList(1 - colFromL0Flag); |
---|
| 1970 | numRefIdx = pcSlice->getNumRefIdx(refList); |
---|
| 1971 | |
---|
| 1972 | if( numRefIdx > 0 ) |
---|
| 1973 | { |
---|
| 1974 | for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > colRefIdx; refIdx-- ) |
---|
| 1975 | { |
---|
| 1976 | TComPic* refPic = pcSlice->getRefPic(refList, refIdx); |
---|
| 1977 | |
---|
| 1978 | if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag( refPic->getLayerId() ) ) ) |
---|
| 1979 | { |
---|
| 1980 | break; |
---|
| 1981 | } |
---|
| 1982 | else |
---|
| 1983 | { |
---|
| 1984 | assert( numRefIdx > 1 ); |
---|
| 1985 | numRefIdx--; |
---|
| 1986 | } |
---|
| 1987 | } |
---|
| 1988 | |
---|
| 1989 | pcSlice->setNumRefIdx( refList, numRefIdx ); |
---|
| 1990 | } |
---|
| 1991 | |
---|
| 1992 | assert( pcSlice->getNumRefIdx(REF_PIC_LIST_0) > 0 && ( pcSlice->isInterP() || (pcSlice->isInterB() && pcSlice->getNumRefIdx(REF_PIC_LIST_1) > 0) ) ); |
---|
| 1993 | } |
---|
| 1994 | #endif |
---|
| 1995 | |
---|
[313] | 1996 | /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice |
---|
| 1997 | // Slice compression |
---|
| 1998 | if (m_pcCfg->getUseASR()) |
---|
| 1999 | { |
---|
| 2000 | m_pcSliceEncoder->setSearchRange(pcSlice); |
---|
| 2001 | } |
---|
| 2002 | |
---|
| 2003 | Bool bGPBcheck=false; |
---|
| 2004 | if ( pcSlice->getSliceType() == B_SLICE) |
---|
| 2005 | { |
---|
| 2006 | if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) ) |
---|
| 2007 | { |
---|
| 2008 | bGPBcheck=true; |
---|
| 2009 | Int i; |
---|
| 2010 | for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ ) |
---|
| 2011 | { |
---|
| 2012 | if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) |
---|
| 2013 | { |
---|
| 2014 | bGPBcheck=false; |
---|
| 2015 | break; |
---|
| 2016 | } |
---|
| 2017 | } |
---|
| 2018 | } |
---|
| 2019 | } |
---|
| 2020 | if(bGPBcheck) |
---|
| 2021 | { |
---|
| 2022 | pcSlice->setMvdL1ZeroFlag(true); |
---|
| 2023 | } |
---|
| 2024 | else |
---|
| 2025 | { |
---|
| 2026 | pcSlice->setMvdL1ZeroFlag(false); |
---|
| 2027 | } |
---|
| 2028 | pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag()); |
---|
| 2029 | |
---|
| 2030 | Double lambda = 0.0; |
---|
| 2031 | Int actualHeadBits = 0; |
---|
| 2032 | Int actualTotalBits = 0; |
---|
| 2033 | Int estimatedBits = 0; |
---|
| 2034 | Int tmpBitsBeforeWriting = 0; |
---|
| 2035 | if ( m_pcCfg->getUseRateCtrl() ) |
---|
| 2036 | { |
---|
| 2037 | Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid ); |
---|
| 2038 | if ( pcPic->getSlice(0)->getSliceType() == I_SLICE ) |
---|
| 2039 | { |
---|
| 2040 | frameLevel = 0; |
---|
| 2041 | } |
---|
| 2042 | m_pcRateCtrl->initRCPic( frameLevel ); |
---|
| 2043 | estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits(); |
---|
| 2044 | |
---|
| 2045 | Int sliceQP = m_pcCfg->getInitialQP(); |
---|
[815] | 2046 | #if POC_RESET_FLAG || POC_RESET_IDC_ENCODER |
---|
[442] | 2047 | if ( ( pocCurr == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified |
---|
| 2048 | #else |
---|
[313] | 2049 | if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified |
---|
[442] | 2050 | #endif |
---|
[313] | 2051 | { |
---|
| 2052 | Int NumberBFrames = ( m_pcCfg->getGOPSize() - 1 ); |
---|
| 2053 | Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames ); |
---|
| 2054 | Double dQPFactor = 0.57*dLambda_scale; |
---|
| 2055 | Int SHIFT_QP = 12; |
---|
| 2056 | Int bitdepth_luma_qp_scale = 0; |
---|
| 2057 | Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP; |
---|
| 2058 | lambda = dQPFactor*pow( 2.0, qp_temp/3.0 ); |
---|
| 2059 | } |
---|
| 2060 | else if ( frameLevel == 0 ) // intra case, but use the model |
---|
| 2061 | { |
---|
| 2062 | m_pcSliceEncoder->calCostSliceI(pcPic); |
---|
| 2063 | if ( m_pcCfg->getIntraPeriod() != 1 ) // do not refine allocated bits for all intra case |
---|
| 2064 | { |
---|
| 2065 | Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits(); |
---|
| 2066 | bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits ); |
---|
| 2067 | if ( bits < 200 ) |
---|
| 2068 | { |
---|
| 2069 | bits = 200; |
---|
| 2070 | } |
---|
| 2071 | m_pcRateCtrl->getRCPic()->setTargetBits( bits ); |
---|
| 2072 | } |
---|
| 2073 | |
---|
| 2074 | list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList(); |
---|
| 2075 | m_pcRateCtrl->getRCPic()->getLCUInitTargetBits(); |
---|
| 2076 | lambda = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType()); |
---|
| 2077 | sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture ); |
---|
| 2078 | } |
---|
| 2079 | else // normal case |
---|
| 2080 | { |
---|
| 2081 | list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList(); |
---|
| 2082 | lambda = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType()); |
---|
| 2083 | sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture ); |
---|
| 2084 | } |
---|
| 2085 | |
---|
[442] | 2086 | #if REPN_FORMAT_IN_VPS |
---|
| 2087 | sliceQP = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, sliceQP ); |
---|
| 2088 | #else |
---|
[313] | 2089 | sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, sliceQP ); |
---|
[442] | 2090 | #endif |
---|
[313] | 2091 | m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP ); |
---|
| 2092 | |
---|
| 2093 | m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda ); |
---|
| 2094 | } |
---|
| 2095 | |
---|
| 2096 | UInt uiNumSlices = 1; |
---|
| 2097 | |
---|
| 2098 | UInt uiInternalAddress = pcPic->getNumPartInCU()-4; |
---|
| 2099 | UInt uiExternalAddress = pcPic->getPicSym()->getNumberOfCUsInFrame()-1; |
---|
| 2100 | UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; |
---|
| 2101 | UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; |
---|
[442] | 2102 | #if REPN_FORMAT_IN_VPS |
---|
| 2103 | UInt uiWidth = pcSlice->getPicWidthInLumaSamples(); |
---|
| 2104 | UInt uiHeight = pcSlice->getPicHeightInLumaSamples(); |
---|
| 2105 | #else |
---|
[313] | 2106 | UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples(); |
---|
| 2107 | UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples(); |
---|
[442] | 2108 | #endif |
---|
[313] | 2109 | while(uiPosX>=uiWidth||uiPosY>=uiHeight) |
---|
| 2110 | { |
---|
| 2111 | uiInternalAddress--; |
---|
| 2112 | uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; |
---|
| 2113 | uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; |
---|
| 2114 | } |
---|
| 2115 | uiInternalAddress++; |
---|
| 2116 | if(uiInternalAddress==pcPic->getNumPartInCU()) |
---|
| 2117 | { |
---|
| 2118 | uiInternalAddress = 0; |
---|
| 2119 | uiExternalAddress++; |
---|
| 2120 | } |
---|
| 2121 | UInt uiRealEndAddress = uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress; |
---|
| 2122 | |
---|
| 2123 | Int p, j; |
---|
| 2124 | UInt uiEncCUAddr; |
---|
| 2125 | |
---|
[906] | 2126 | pcPic->getPicSym()->initTiles(pcSlice->getPPS()); |
---|
[313] | 2127 | |
---|
[442] | 2128 | #if N0383_IL_CONSTRAINED_TILE_SETS_SEI |
---|
| 2129 | if (m_pcCfg->getInterLayerConstrainedTileSetsSEIEnabled()) |
---|
| 2130 | { |
---|
| 2131 | xBuildTileSetsMap(pcPic->getPicSym()); |
---|
| 2132 | } |
---|
| 2133 | #endif |
---|
| 2134 | |
---|
[313] | 2135 | // Allocate some coders, now we know how many tiles there are. |
---|
[906] | 2136 | #if WPP_FIX |
---|
| 2137 | const Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams(); |
---|
| 2138 | #else |
---|
[313] | 2139 | Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams(); |
---|
[906] | 2140 | #endif |
---|
[313] | 2141 | |
---|
| 2142 | //generate the Coding Order Map and Inverse Coding Order Map |
---|
| 2143 | for(p=0, uiEncCUAddr=0; p<pcPic->getPicSym()->getNumberOfCUsInFrame(); p++, uiEncCUAddr = pcPic->getPicSym()->xCalculateNxtCUAddr(uiEncCUAddr)) |
---|
| 2144 | { |
---|
| 2145 | pcPic->getPicSym()->setCUOrderMap(p, uiEncCUAddr); |
---|
| 2146 | pcPic->getPicSym()->setInverseCUOrderMap(uiEncCUAddr, p); |
---|
| 2147 | } |
---|
| 2148 | pcPic->getPicSym()->setCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame()); |
---|
| 2149 | pcPic->getPicSym()->setInverseCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame()); |
---|
| 2150 | |
---|
| 2151 | // Allocate some coders, now we know how many tiles there are. |
---|
| 2152 | m_pcEncTop->createWPPCoders(iNumSubstreams); |
---|
| 2153 | pcSbacCoders = m_pcEncTop->getSbacCoders(); |
---|
| 2154 | pcSubstreamsOut = new TComOutputBitstream[iNumSubstreams]; |
---|
| 2155 | |
---|
| 2156 | UInt startCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries |
---|
| 2157 | UInt startCUAddrSlice = 0; // used to keep track of current slice's starting CU addr. |
---|
| 2158 | pcSlice->setSliceCurStartCUAddr( startCUAddrSlice ); // Setting "start CU addr" for current slice |
---|
| 2159 | m_storedStartCUAddrForEncodingSlice.clear(); |
---|
| 2160 | |
---|
| 2161 | UInt startCUAddrSliceSegmentIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries |
---|
| 2162 | UInt startCUAddrSliceSegment = 0; // used to keep track of current Dependent slice's starting CU addr. |
---|
| 2163 | pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment ); // Setting "start CU addr" for current Dependent slice |
---|
| 2164 | |
---|
| 2165 | m_storedStartCUAddrForEncodingSliceSegment.clear(); |
---|
| 2166 | UInt nextCUAddr = 0; |
---|
| 2167 | m_storedStartCUAddrForEncodingSlice.push_back (nextCUAddr); |
---|
| 2168 | startCUAddrSliceIdx++; |
---|
| 2169 | m_storedStartCUAddrForEncodingSliceSegment.push_back(nextCUAddr); |
---|
| 2170 | startCUAddrSliceSegmentIdx++; |
---|
| 2171 | #if AVC_BASE |
---|
[906] | 2172 | #if VPS_AVC_BL_FLAG_REMOVAL |
---|
| 2173 | if( m_layerId == 0 && m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() ) |
---|
| 2174 | #else |
---|
[313] | 2175 | if( m_layerId == 0 && m_pcEncTop->getVPS()->getAvcBaseLayerFlag() ) |
---|
[906] | 2176 | #endif |
---|
[313] | 2177 | { |
---|
| 2178 | pcPic->getPicYuvOrg()->copyToPic( pcPic->getPicYuvRec() ); |
---|
[494] | 2179 | #if O0194_WEIGHTED_PREDICTION_CGS |
---|
| 2180 | // Calculate for the base layer to be used in EL as Inter layer reference |
---|
[588] | 2181 | if( m_pcEncTop->getInterLayerWeightedPredFlag() ) |
---|
| 2182 | { |
---|
| 2183 | m_pcSliceEncoder->estimateILWpParam( pcSlice ); |
---|
| 2184 | } |
---|
[494] | 2185 | #endif |
---|
[906] | 2186 | |
---|
| 2187 | if( pcSubstreamsOut ) |
---|
| 2188 | { |
---|
| 2189 | delete[] pcSubstreamsOut; |
---|
| 2190 | pcSubstreamsOut = NULL; |
---|
| 2191 | } |
---|
| 2192 | |
---|
| 2193 | if( pcBitstreamRedirect ) |
---|
| 2194 | { |
---|
| 2195 | delete pcBitstreamRedirect; |
---|
| 2196 | pcBitstreamRedirect = NULL; |
---|
| 2197 | } |
---|
| 2198 | |
---|
[313] | 2199 | return; |
---|
| 2200 | } |
---|
| 2201 | #endif |
---|
| 2202 | |
---|
| 2203 | while(nextCUAddr<uiRealEndAddress) // determine slice boundaries |
---|
| 2204 | { |
---|
| 2205 | pcSlice->setNextSlice ( false ); |
---|
| 2206 | pcSlice->setNextSliceSegment( false ); |
---|
| 2207 | assert(pcPic->getNumAllocatedSlice() == startCUAddrSliceIdx); |
---|
| 2208 | m_pcSliceEncoder->precompressSlice( pcPic ); |
---|
| 2209 | m_pcSliceEncoder->compressSlice ( pcPic ); |
---|
| 2210 | |
---|
| 2211 | Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextSliceSegment()); |
---|
| 2212 | if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU)) |
---|
| 2213 | { |
---|
| 2214 | startCUAddrSlice = pcSlice->getSliceCurEndCUAddr(); |
---|
| 2215 | // Reconstruction slice |
---|
| 2216 | m_storedStartCUAddrForEncodingSlice.push_back(startCUAddrSlice); |
---|
| 2217 | startCUAddrSliceIdx++; |
---|
| 2218 | // Dependent slice |
---|
| 2219 | if (startCUAddrSliceSegmentIdx>0 && m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx-1] != startCUAddrSlice) |
---|
| 2220 | { |
---|
| 2221 | m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSlice); |
---|
| 2222 | startCUAddrSliceSegmentIdx++; |
---|
| 2223 | } |
---|
| 2224 | |
---|
| 2225 | if (startCUAddrSlice < uiRealEndAddress) |
---|
| 2226 | { |
---|
| 2227 | pcPic->allocateNewSlice(); |
---|
| 2228 | pcPic->setCurrSliceIdx ( startCUAddrSliceIdx-1 ); |
---|
| 2229 | m_pcSliceEncoder->setSliceIdx ( startCUAddrSliceIdx-1 ); |
---|
| 2230 | pcSlice = pcPic->getSlice ( startCUAddrSliceIdx-1 ); |
---|
| 2231 | pcSlice->copySliceInfo ( pcPic->getSlice(0) ); |
---|
| 2232 | pcSlice->setSliceIdx ( startCUAddrSliceIdx-1 ); |
---|
| 2233 | pcSlice->setSliceCurStartCUAddr ( startCUAddrSlice ); |
---|
| 2234 | pcSlice->setSliceSegmentCurStartCUAddr ( startCUAddrSlice ); |
---|
| 2235 | pcSlice->setSliceBits(0); |
---|
[494] | 2236 | #if SVC_EXTENSION |
---|
| 2237 | // copy reference list modification info from the first slice, assuming that this information is the same across all slices in the picture |
---|
| 2238 | memcpy( pcSlice->getRefPicListModification(), pcPic->getSlice(0)->getRefPicListModification(), sizeof(TComRefPicListModification) ); |
---|
| 2239 | #endif |
---|
[313] | 2240 | uiNumSlices ++; |
---|
| 2241 | } |
---|
| 2242 | } |
---|
| 2243 | else if (pcSlice->isNextSliceSegment() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)) |
---|
| 2244 | { |
---|
| 2245 | startCUAddrSliceSegment = pcSlice->getSliceSegmentCurEndCUAddr(); |
---|
| 2246 | m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSliceSegment); |
---|
| 2247 | startCUAddrSliceSegmentIdx++; |
---|
| 2248 | pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment ); |
---|
| 2249 | } |
---|
| 2250 | else |
---|
| 2251 | { |
---|
| 2252 | startCUAddrSlice = pcSlice->getSliceCurEndCUAddr(); |
---|
| 2253 | startCUAddrSliceSegment = pcSlice->getSliceSegmentCurEndCUAddr(); |
---|
| 2254 | } |
---|
| 2255 | |
---|
| 2256 | nextCUAddr = (startCUAddrSlice > startCUAddrSliceSegment) ? startCUAddrSlice : startCUAddrSliceSegment; |
---|
| 2257 | } |
---|
| 2258 | m_storedStartCUAddrForEncodingSlice.push_back( pcSlice->getSliceCurEndCUAddr()); |
---|
| 2259 | startCUAddrSliceIdx++; |
---|
| 2260 | m_storedStartCUAddrForEncodingSliceSegment.push_back(pcSlice->getSliceCurEndCUAddr()); |
---|
| 2261 | startCUAddrSliceSegmentIdx++; |
---|
| 2262 | |
---|
| 2263 | pcSlice = pcPic->getSlice(0); |
---|
| 2264 | |
---|
| 2265 | // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas |
---|
[540] | 2266 | if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoLcuBoundary() ) |
---|
| 2267 | { |
---|
| 2268 | m_pcSAO->getPreDBFStatistics(pcPic); |
---|
| 2269 | } |
---|
[313] | 2270 | //-- Loop filter |
---|
| 2271 | Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag(); |
---|
| 2272 | m_pcLoopFilter->setCfg(bLFCrossTileBoundary); |
---|
| 2273 | if ( m_pcCfg->getDeblockingFilterMetric() ) |
---|
| 2274 | { |
---|
| 2275 | dblMetric(pcPic, uiNumSlices); |
---|
| 2276 | } |
---|
| 2277 | m_pcLoopFilter->loopFilterPic( pcPic ); |
---|
| 2278 | |
---|
| 2279 | /////////////////////////////////////////////////////////////////////////////////////////////////// File writing |
---|
| 2280 | // Set entropy coder |
---|
| 2281 | m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice ); |
---|
| 2282 | |
---|
| 2283 | /* write various header sets. */ |
---|
| 2284 | if ( m_bSeqFirst ) |
---|
| 2285 | { |
---|
| 2286 | #if SVC_EXTENSION |
---|
[815] | 2287 | OutputNALUnit nalu( NAL_UNIT_VPS, 0, 0 ); // The value of nuh_layer_id of VPS NAL unit shall be equal to 0. |
---|
[313] | 2288 | #if AVC_BASE |
---|
[906] | 2289 | #if VPS_AVC_BL_FLAG_REMOVAL |
---|
| 2290 | if( ( m_layerId == 1 && m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() ) || ( m_layerId == 0 && !m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() ) ) |
---|
| 2291 | #else |
---|
[313] | 2292 | if( ( m_layerId == 1 && m_pcEncTop->getVPS()->getAvcBaseLayerFlag() ) || ( m_layerId == 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() ) ) |
---|
[906] | 2293 | #endif |
---|
[313] | 2294 | #else |
---|
| 2295 | if( m_layerId == 0 ) |
---|
| 2296 | #endif |
---|
| 2297 | { |
---|
| 2298 | #else |
---|
| 2299 | OutputNALUnit nalu(NAL_UNIT_VPS); |
---|
| 2300 | #endif |
---|
[547] | 2301 | #if VPS_VUI_OFFSET |
---|
| 2302 | // The following code also calculates the VPS VUI offset |
---|
| 2303 | #endif |
---|
[588] | 2304 | #if !P0125_REVERT_VPS_EXTN_OFFSET_TO_RESERVED |
---|
[494] | 2305 | #if VPS_EXTN_OFFSET_CALC |
---|
| 2306 | OutputNALUnit tempNalu(NAL_UNIT_VPS, 0, 0 ); // The value of nuh_layer_id of VPS NAL unit shall be equal to 0. |
---|
| 2307 | m_pcEntropyCoder->setBitstream(&tempNalu.m_Bitstream); |
---|
| 2308 | m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS()); // Use to calculate the VPS extension offset |
---|
| 2309 | #endif |
---|
[588] | 2310 | #endif |
---|
[313] | 2311 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2312 | m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS()); |
---|
| 2313 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2314 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 2315 | actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8; |
---|
| 2316 | #if SVC_EXTENSION |
---|
| 2317 | } |
---|
| 2318 | #endif |
---|
| 2319 | |
---|
| 2320 | #if SVC_EXTENSION |
---|
| 2321 | nalu = NALUnit(NAL_UNIT_SPS, 0, m_layerId); |
---|
| 2322 | #else |
---|
| 2323 | nalu = NALUnit(NAL_UNIT_SPS); |
---|
| 2324 | #endif |
---|
[815] | 2325 | #if Q0078_ADD_LAYER_SETS |
---|
| 2326 | if (m_pcEncTop->getVPS()->getNumDirectRefLayers(m_layerId) == 0 && m_pcEncTop->getVPS()->getNumAddLayerSets() > 0) |
---|
| 2327 | { |
---|
| 2328 | nalu.m_layerId = 0; // For independent base layer rewriting |
---|
| 2329 | } |
---|
| 2330 | #endif |
---|
[313] | 2331 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2332 | if (m_bSeqFirst) |
---|
| 2333 | { |
---|
| 2334 | pcSlice->getSPS()->setNumLongTermRefPicSPS(m_numLongTermRefPicSPS); |
---|
| 2335 | for (Int k = 0; k < m_numLongTermRefPicSPS; k++) |
---|
| 2336 | { |
---|
| 2337 | pcSlice->getSPS()->setLtRefPicPocLsbSps(k, m_ltRefPicPocLsbSps[k]); |
---|
| 2338 | pcSlice->getSPS()->setUsedByCurrPicLtSPSFlag(k, m_ltRefPicUsedByCurrPicFlag[k]); |
---|
| 2339 | } |
---|
| 2340 | } |
---|
| 2341 | if( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) |
---|
| 2342 | { |
---|
| 2343 | UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1); |
---|
| 2344 | UInt numDU = ( m_pcCfg->getSliceMode() == 1 ) ? ( pcPic->getNumCUsInFrame() / maxCU ) : ( 0 ); |
---|
| 2345 | if( pcPic->getNumCUsInFrame() % maxCU != 0 || numDU == 0 ) |
---|
| 2346 | { |
---|
| 2347 | numDU ++; |
---|
| 2348 | } |
---|
| 2349 | pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->setNumDU( numDU ); |
---|
| 2350 | pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) ); |
---|
| 2351 | } |
---|
| 2352 | if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) |
---|
| 2353 | { |
---|
| 2354 | pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true ); |
---|
| 2355 | } |
---|
[540] | 2356 | #if O0092_0094_DEPENDENCY_CONSTRAINT |
---|
| 2357 | assert( pcSlice->getSPS()->getLayerId() == 0 || pcSlice->getSPS()->getLayerId() == m_layerId || m_pcEncTop->getVPS()->getRecursiveRefLayerFlag(m_layerId, pcSlice->getSPS()->getLayerId()) ); |
---|
| 2358 | #endif |
---|
[313] | 2359 | m_pcEntropyCoder->encodeSPS(pcSlice->getSPS()); |
---|
| 2360 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2361 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 2362 | actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8; |
---|
| 2363 | |
---|
| 2364 | #if SVC_EXTENSION |
---|
| 2365 | nalu = NALUnit(NAL_UNIT_PPS, 0, m_layerId); |
---|
| 2366 | #else |
---|
| 2367 | nalu = NALUnit(NAL_UNIT_PPS); |
---|
| 2368 | #endif |
---|
[815] | 2369 | #if Q0078_ADD_LAYER_SETS |
---|
| 2370 | if (m_pcEncTop->getVPS()->getNumDirectRefLayers(m_layerId) == 0 && m_pcEncTop->getVPS()->getNumAddLayerSets() > 0) |
---|
| 2371 | { |
---|
| 2372 | nalu.m_layerId = 0; // For independent base layer rewriting |
---|
| 2373 | } |
---|
| 2374 | #endif |
---|
[313] | 2375 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
[540] | 2376 | #if O0092_0094_DEPENDENCY_CONSTRAINT |
---|
| 2377 | assert( pcSlice->getPPS()->getPPSId() == 0 || pcSlice->getPPS()->getPPSId() == m_layerId || m_pcEncTop->getVPS()->getRecursiveRefLayerFlag(m_layerId, pcSlice->getPPS()->getPPSId()) ); |
---|
| 2378 | #endif |
---|
[713] | 2379 | m_pcEntropyCoder->encodePPS(pcSlice->getPPS() |
---|
| 2380 | #if Q0048_CGS_3D_ASYMLUT |
---|
| 2381 | , & m_Enc3DAsymLUTPPS |
---|
| 2382 | #endif |
---|
| 2383 | ); |
---|
[313] | 2384 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2385 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 2386 | actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8; |
---|
| 2387 | |
---|
| 2388 | xCreateLeadingSEIMessages(accessUnit, pcSlice->getSPS()); |
---|
| 2389 | |
---|
[644] | 2390 | #if O0164_MULTI_LAYER_HRD |
---|
| 2391 | if (pcSlice->getLayerId() == 0 && m_pcEncTop->getVPS()->getVpsVuiBspHrdPresentFlag()) |
---|
| 2392 | { |
---|
[906] | 2393 | #if VPS_VUI_BSP_HRD_PARAMS |
---|
| 2394 | TComVPS *vps = m_pcEncTop->getVPS(); |
---|
| 2395 | for(Int i = 0; i < vps->getNumOutputLayerSets(); i++) |
---|
| 2396 | { |
---|
| 2397 | for(Int k = 0; k < vps->getNumSignalledPartitioningSchemes(i); k++) |
---|
| 2398 | { |
---|
| 2399 | for(Int l = 0; l < vps->getNumPartitionsInSchemeMinus1(i, k)+1; l++) |
---|
| 2400 | { |
---|
| 2401 | #endif |
---|
| 2402 | nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, 1); |
---|
| 2403 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 2404 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2405 | #if VPS_VUI_BSP_HRD_PARAMS |
---|
| 2406 | SEIScalableNesting *scalableBspNestingSei = xCreateBspNestingSEI(pcSlice, i, k, l); |
---|
| 2407 | #else |
---|
| 2408 | SEIScalableNesting *scalableBspNestingSei = xCreateBspNestingSEI(pcSlice); |
---|
| 2409 | #endif |
---|
| 2410 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, *scalableBspNestingSei, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 2411 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
[644] | 2412 | |
---|
[906] | 2413 | UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit); |
---|
| 2414 | UInt offsetPosition = m_activeParameterSetSEIPresentInAU |
---|
| 2415 | + m_bufferingPeriodSEIPresentInAU |
---|
| 2416 | + m_pictureTimingSEIPresentInAU |
---|
| 2417 | + m_nestedPictureTimingSEIPresentInAU; // Insert SEI after APS, BP and PT SEI |
---|
| 2418 | AccessUnit::iterator it; |
---|
| 2419 | for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++) |
---|
| 2420 | { |
---|
| 2421 | it++; |
---|
| 2422 | } |
---|
| 2423 | accessUnit.insert(it, new NALUnitEBSP(nalu)); |
---|
| 2424 | #if VPS_VUI_BSP_HRD_PARAMS |
---|
| 2425 | } |
---|
| 2426 | } |
---|
[644] | 2427 | } |
---|
[906] | 2428 | #endif |
---|
[644] | 2429 | } |
---|
| 2430 | #endif |
---|
| 2431 | |
---|
[313] | 2432 | m_bSeqFirst = false; |
---|
| 2433 | } |
---|
[713] | 2434 | #if Q0048_CGS_3D_ASYMLUT |
---|
| 2435 | else if( m_pcCfg->getCGSFlag() && pcSlice->getLayerId() && pcSlice->getCGSOverWritePPS() ) |
---|
| 2436 | { |
---|
| 2437 | #if SVC_EXTENSION |
---|
| 2438 | OutputNALUnit nalu(NAL_UNIT_PPS, 0, m_layerId); |
---|
| 2439 | #endif |
---|
[313] | 2440 | |
---|
[713] | 2441 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2442 | m_pcEntropyCoder->encodePPS(pcSlice->getPPS() , &m_Enc3DAsymLUTPPS ); |
---|
| 2443 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2444 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 2445 | } |
---|
| 2446 | #endif |
---|
| 2447 | |
---|
[313] | 2448 | if (writeSOP) // write SOP description SEI (if enabled) at the beginning of GOP |
---|
| 2449 | { |
---|
| 2450 | Int SOPcurrPOC = pocCurr; |
---|
| 2451 | |
---|
| 2452 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); |
---|
| 2453 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 2454 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2455 | |
---|
| 2456 | SEISOPDescription SOPDescriptionSEI; |
---|
| 2457 | SOPDescriptionSEI.m_sopSeqParameterSetId = pcSlice->getSPS()->getSPSId(); |
---|
| 2458 | |
---|
| 2459 | UInt i = 0; |
---|
| 2460 | UInt prevEntryId = iGOPid; |
---|
| 2461 | for (j = iGOPid; j < m_iGopSize; j++) |
---|
| 2462 | { |
---|
| 2463 | Int deltaPOC = m_pcCfg->getGOPEntry(j).m_POC - m_pcCfg->getGOPEntry(prevEntryId).m_POC; |
---|
| 2464 | if ((SOPcurrPOC + deltaPOC) < m_pcCfg->getFramesToBeEncoded()) |
---|
| 2465 | { |
---|
| 2466 | SOPcurrPOC += deltaPOC; |
---|
[595] | 2467 | SOPDescriptionSEI.m_sopDescVclNaluType[i] = getNalUnitType(SOPcurrPOC, m_iLastIDR, isField); |
---|
[313] | 2468 | SOPDescriptionSEI.m_sopDescTemporalId[i] = m_pcCfg->getGOPEntry(j).m_temporalId; |
---|
| 2469 | SOPDescriptionSEI.m_sopDescStRpsIdx[i] = m_pcEncTop->getReferencePictureSetIdxForSOP(pcSlice, SOPcurrPOC, j); |
---|
| 2470 | SOPDescriptionSEI.m_sopDescPocDelta[i] = deltaPOC; |
---|
| 2471 | |
---|
| 2472 | prevEntryId = j; |
---|
| 2473 | i++; |
---|
| 2474 | } |
---|
| 2475 | } |
---|
| 2476 | |
---|
| 2477 | SOPDescriptionSEI.m_numPicsInSopMinus1 = i - 1; |
---|
| 2478 | |
---|
[644] | 2479 | #if O0164_MULTI_LAYER_HRD |
---|
| 2480 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 2481 | #else |
---|
[313] | 2482 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, pcSlice->getSPS()); |
---|
[644] | 2483 | #endif |
---|
[313] | 2484 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2485 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 2486 | |
---|
| 2487 | writeSOP = false; |
---|
| 2488 | } |
---|
[815] | 2489 | #if Q0189_TMVP_CONSTRAINTS |
---|
| 2490 | if( m_pcEncTop->getTMVPConstraintsSEIEnabled() == 1 && |
---|
| 2491 | (m_pcEncTop->getTMVPModeId() == 1 || m_pcEncTop->getTMVPModeId() == 2) && |
---|
| 2492 | pcSlice->getLayerId() >0 && |
---|
| 2493 | (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP)) |
---|
| 2494 | { |
---|
| 2495 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); |
---|
| 2496 | SEITMVPConstrains seiTMVPConstrains; |
---|
| 2497 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 2498 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2499 | seiTMVPConstrains.no_intra_layer_col_pic_flag = 1; |
---|
| 2500 | seiTMVPConstrains.prev_pics_not_used_flag = 1; |
---|
| 2501 | #if O0164_MULTI_LAYER_HRD |
---|
| 2502 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiTMVPConstrains, m_pcEncTop->getVPS(), pcSlice->getSPS() ); |
---|
| 2503 | #else |
---|
| 2504 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiTMVPConstrains, pcSlice->getSPS() ); |
---|
| 2505 | #endif |
---|
| 2506 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2507 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 2508 | } |
---|
| 2509 | #endif |
---|
| 2510 | #if Q0247_FRAME_FIELD_INFO |
---|
| 2511 | if( pcSlice->getLayerId()> 0 && |
---|
| 2512 | ( (m_pcCfg->getProgressiveSourceFlag() && m_pcCfg->getInterlacedSourceFlag()) || m_pcCfg->getFrameFieldInfoPresentFlag())) |
---|
| 2513 | { |
---|
| 2514 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); |
---|
| 2515 | SEIFrameFieldInfo seiFFInfo; |
---|
| 2516 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 2517 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2518 | seiFFInfo.m_ffinfo_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0; |
---|
| 2519 | #if O0164_MULTI_LAYER_HRD |
---|
| 2520 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiFFInfo, m_pcEncTop->getVPS(), pcSlice->getSPS() ); |
---|
| 2521 | #else |
---|
| 2522 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiFFInfo, pcSlice->getSPS() ); |
---|
| 2523 | #endif |
---|
| 2524 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2525 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 2526 | } |
---|
| 2527 | #endif |
---|
[313] | 2528 | |
---|
| 2529 | if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) && |
---|
| 2530 | ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && |
---|
| 2531 | ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) |
---|
| 2532 | || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) ) |
---|
| 2533 | { |
---|
| 2534 | if( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) |
---|
| 2535 | { |
---|
| 2536 | UInt numDU = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumDU(); |
---|
| 2537 | pictureTimingSEI.m_numDecodingUnitsMinus1 = ( numDU - 1 ); |
---|
| 2538 | pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = false; |
---|
| 2539 | |
---|
| 2540 | if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL ) |
---|
| 2541 | { |
---|
| 2542 | pictureTimingSEI.m_numNalusInDuMinus1 = new UInt[ numDU ]; |
---|
| 2543 | } |
---|
| 2544 | if( pictureTimingSEI.m_duCpbRemovalDelayMinus1 == NULL ) |
---|
| 2545 | { |
---|
| 2546 | pictureTimingSEI.m_duCpbRemovalDelayMinus1 = new UInt[ numDU ]; |
---|
| 2547 | } |
---|
| 2548 | if( accumBitsDU == NULL ) |
---|
| 2549 | { |
---|
| 2550 | accumBitsDU = new UInt[ numDU ]; |
---|
| 2551 | } |
---|
| 2552 | if( accumNalsDU == NULL ) |
---|
| 2553 | { |
---|
| 2554 | accumNalsDU = new UInt[ numDU ]; |
---|
| 2555 | } |
---|
| 2556 | } |
---|
[442] | 2557 | pictureTimingSEI.m_auCpbRemovalDelay = std::min<Int>(std::max<Int>(1, m_totalCoded - m_lastBPSEI), static_cast<Int>(pow(2, static_cast<double>(pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getCpbRemovalDelayLengthMinus1()+1)))); // Syntax element signalled as minus, hence the . |
---|
[815] | 2558 | #if POC_RESET_FLAG || POC_RESET_IDC_ENCODER |
---|
[713] | 2559 | pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pocCurr - m_totalCoded; |
---|
[442] | 2560 | #else |
---|
[713] | 2561 | pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pcSlice->getPOC() - m_totalCoded; |
---|
[442] | 2562 | #endif |
---|
[713] | 2563 | #if EFFICIENT_FIELD_IRAP |
---|
| 2564 | if(IRAPGOPid > 0 && IRAPGOPid < m_iGopSize) |
---|
| 2565 | { |
---|
| 2566 | // if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation |
---|
| 2567 | pictureTimingSEI.m_picDpbOutputDelay ++; |
---|
| 2568 | } |
---|
| 2569 | #endif |
---|
[313] | 2570 | Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2; |
---|
| 2571 | pictureTimingSEI.m_picDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay; |
---|
| 2572 | if( m_pcCfg->getDecodingUnitInfoSEIEnabled() ) |
---|
| 2573 | { |
---|
| 2574 | picSptDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay; |
---|
| 2575 | } |
---|
| 2576 | } |
---|
| 2577 | |
---|
| 2578 | if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) && |
---|
| 2579 | ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && |
---|
| 2580 | ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) |
---|
| 2581 | || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) ) |
---|
| 2582 | { |
---|
| 2583 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); |
---|
| 2584 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 2585 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2586 | |
---|
| 2587 | SEIBufferingPeriod sei_buffering_period; |
---|
| 2588 | |
---|
| 2589 | UInt uiInitialCpbRemovalDelay = (90000/2); // 0.5 sec |
---|
| 2590 | sei_buffering_period.m_initialCpbRemovalDelay [0][0] = uiInitialCpbRemovalDelay; |
---|
| 2591 | sei_buffering_period.m_initialCpbRemovalDelayOffset[0][0] = uiInitialCpbRemovalDelay; |
---|
| 2592 | sei_buffering_period.m_initialCpbRemovalDelay [0][1] = uiInitialCpbRemovalDelay; |
---|
| 2593 | sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1] = uiInitialCpbRemovalDelay; |
---|
| 2594 | |
---|
| 2595 | Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale(); |
---|
| 2596 | |
---|
| 2597 | UInt uiTmp = (UInt)( dTmp * 90000.0 ); |
---|
| 2598 | uiInitialCpbRemovalDelay -= uiTmp; |
---|
| 2599 | uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 ); |
---|
| 2600 | sei_buffering_period.m_initialAltCpbRemovalDelay [0][0] = uiInitialCpbRemovalDelay; |
---|
| 2601 | sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0] = uiInitialCpbRemovalDelay; |
---|
| 2602 | sei_buffering_period.m_initialAltCpbRemovalDelay [0][1] = uiInitialCpbRemovalDelay; |
---|
| 2603 | sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1] = uiInitialCpbRemovalDelay; |
---|
| 2604 | |
---|
| 2605 | sei_buffering_period.m_rapCpbParamsPresentFlag = 0; |
---|
| 2606 | //for the concatenation, it can be set to one during splicing. |
---|
| 2607 | sei_buffering_period.m_concatenationFlag = 0; |
---|
| 2608 | //since the temporal layer HRD is not ready, we assumed it is fixed |
---|
| 2609 | sei_buffering_period.m_auCpbRemovalDelayDelta = 1; |
---|
| 2610 | sei_buffering_period.m_cpbDelayOffset = 0; |
---|
| 2611 | sei_buffering_period.m_dpbDelayOffset = 0; |
---|
| 2612 | |
---|
[644] | 2613 | #if O0164_MULTI_LAYER_HRD |
---|
| 2614 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 2615 | #else |
---|
[313] | 2616 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, pcSlice->getSPS()); |
---|
[644] | 2617 | #endif |
---|
[313] | 2618 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2619 | { |
---|
| 2620 | UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit); |
---|
| 2621 | UInt offsetPosition = m_activeParameterSetSEIPresentInAU; // Insert BP SEI after APS SEI |
---|
| 2622 | AccessUnit::iterator it; |
---|
| 2623 | for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++) |
---|
| 2624 | { |
---|
| 2625 | it++; |
---|
| 2626 | } |
---|
| 2627 | accessUnit.insert(it, new NALUnitEBSP(nalu)); |
---|
| 2628 | m_bufferingPeriodSEIPresentInAU = true; |
---|
| 2629 | } |
---|
| 2630 | |
---|
| 2631 | if (m_pcCfg->getScalableNestingSEIEnabled()) |
---|
| 2632 | { |
---|
| 2633 | OutputNALUnit naluTmp(NAL_UNIT_PREFIX_SEI); |
---|
| 2634 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 2635 | m_pcEntropyCoder->setBitstream(&naluTmp.m_Bitstream); |
---|
| 2636 | scalableNestingSEI.m_nestedSEIs.clear(); |
---|
| 2637 | scalableNestingSEI.m_nestedSEIs.push_back(&sei_buffering_period); |
---|
[644] | 2638 | #if O0164_MULTI_LAYER_HRD |
---|
| 2639 | m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 2640 | #else |
---|
[313] | 2641 | m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, pcSlice->getSPS()); |
---|
[644] | 2642 | #endif |
---|
[313] | 2643 | writeRBSPTrailingBits(naluTmp.m_Bitstream); |
---|
| 2644 | UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit); |
---|
| 2645 | UInt offsetPosition = m_activeParameterSetSEIPresentInAU + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU; // Insert BP SEI after non-nested APS, BP and PT SEIs |
---|
| 2646 | AccessUnit::iterator it; |
---|
| 2647 | for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++) |
---|
| 2648 | { |
---|
| 2649 | it++; |
---|
| 2650 | } |
---|
| 2651 | accessUnit.insert(it, new NALUnitEBSP(naluTmp)); |
---|
| 2652 | m_nestedBufferingPeriodSEIPresentInAU = true; |
---|
| 2653 | } |
---|
| 2654 | |
---|
| 2655 | m_lastBPSEI = m_totalCoded; |
---|
| 2656 | m_cpbRemovalDelay = 0; |
---|
| 2657 | } |
---|
| 2658 | m_cpbRemovalDelay ++; |
---|
| 2659 | if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) ) |
---|
| 2660 | { |
---|
| 2661 | if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !pcSlice->getRapPicFlag() ) |
---|
| 2662 | { |
---|
| 2663 | // Gradual decoding refresh SEI |
---|
| 2664 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); |
---|
| 2665 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 2666 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2667 | |
---|
| 2668 | SEIGradualDecodingRefreshInfo seiGradualDecodingRefreshInfo; |
---|
| 2669 | seiGradualDecodingRefreshInfo.m_gdrForegroundFlag = true; // Indicating all "foreground" |
---|
| 2670 | |
---|
[644] | 2671 | #if O0164_MULTI_LAYER_HRD |
---|
| 2672 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, m_pcEncTop->getVPS(), pcSlice->getSPS() ); |
---|
| 2673 | #else |
---|
[313] | 2674 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, pcSlice->getSPS() ); |
---|
[644] | 2675 | #endif |
---|
[313] | 2676 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2677 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 2678 | } |
---|
| 2679 | // Recovery point SEI |
---|
| 2680 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); |
---|
| 2681 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 2682 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2683 | |
---|
| 2684 | SEIRecoveryPoint sei_recovery_point; |
---|
| 2685 | sei_recovery_point.m_recoveryPocCnt = 0; |
---|
[815] | 2686 | #if POC_RESET_FLAG || POC_RESET_IDC_ENCODER |
---|
[442] | 2687 | sei_recovery_point.m_exactMatchingFlag = ( pocCurr == 0 ) ? (true) : (false); |
---|
| 2688 | #else |
---|
[313] | 2689 | sei_recovery_point.m_exactMatchingFlag = ( pcSlice->getPOC() == 0 ) ? (true) : (false); |
---|
[442] | 2690 | #endif |
---|
[313] | 2691 | sei_recovery_point.m_brokenLinkFlag = false; |
---|
[713] | 2692 | #if ALLOW_RECOVERY_POINT_AS_RAP |
---|
| 2693 | if(m_pcCfg->getDecodingRefreshType() == 3) |
---|
| 2694 | { |
---|
| 2695 | m_iLastRecoveryPicPOC = pocCurr; |
---|
| 2696 | } |
---|
| 2697 | #endif |
---|
[313] | 2698 | |
---|
[644] | 2699 | #if O0164_MULTI_LAYER_HRD |
---|
| 2700 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, m_pcEncTop->getVPS(), pcSlice->getSPS() ); |
---|
| 2701 | #else |
---|
[313] | 2702 | m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, pcSlice->getSPS() ); |
---|
[644] | 2703 | #endif |
---|
[313] | 2704 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 2705 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 2706 | } |
---|
| 2707 | |
---|
| 2708 | /* use the main bitstream buffer for storing the marshalled picture */ |
---|
| 2709 | m_pcEntropyCoder->setBitstream(NULL); |
---|
| 2710 | |
---|
| 2711 | startCUAddrSliceIdx = 0; |
---|
| 2712 | startCUAddrSlice = 0; |
---|
| 2713 | |
---|
| 2714 | startCUAddrSliceSegmentIdx = 0; |
---|
| 2715 | startCUAddrSliceSegment = 0; |
---|
| 2716 | nextCUAddr = 0; |
---|
| 2717 | pcSlice = pcPic->getSlice(startCUAddrSliceIdx); |
---|
| 2718 | |
---|
| 2719 | Int processingState = (pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE); |
---|
| 2720 | Bool skippedSlice=false; |
---|
| 2721 | while (nextCUAddr < uiRealEndAddress) // Iterate over all slices |
---|
| 2722 | { |
---|
| 2723 | switch(processingState) |
---|
| 2724 | { |
---|
| 2725 | case ENCODE_SLICE: |
---|
| 2726 | { |
---|
| 2727 | pcSlice->setNextSlice ( false ); |
---|
| 2728 | pcSlice->setNextSliceSegment( false ); |
---|
| 2729 | if (nextCUAddr == m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx]) |
---|
| 2730 | { |
---|
| 2731 | pcSlice = pcPic->getSlice(startCUAddrSliceIdx); |
---|
| 2732 | if(startCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE) |
---|
| 2733 | { |
---|
| 2734 | pcSlice->checkColRefIdx(startCUAddrSliceIdx, pcPic); |
---|
| 2735 | } |
---|
| 2736 | pcPic->setCurrSliceIdx(startCUAddrSliceIdx); |
---|
| 2737 | m_pcSliceEncoder->setSliceIdx(startCUAddrSliceIdx); |
---|
| 2738 | assert(startCUAddrSliceIdx == pcSlice->getSliceIdx()); |
---|
| 2739 | // Reconstruction slice |
---|
| 2740 | pcSlice->setSliceCurStartCUAddr( nextCUAddr ); // to be used in encodeSlice() + context restriction |
---|
| 2741 | pcSlice->setSliceCurEndCUAddr ( m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx+1 ] ); |
---|
| 2742 | // Dependent slice |
---|
| 2743 | pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr ); // to be used in encodeSlice() + context restriction |
---|
| 2744 | pcSlice->setSliceSegmentCurEndCUAddr ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] ); |
---|
| 2745 | |
---|
| 2746 | pcSlice->setNextSlice ( true ); |
---|
| 2747 | |
---|
| 2748 | startCUAddrSliceIdx++; |
---|
| 2749 | startCUAddrSliceSegmentIdx++; |
---|
| 2750 | } |
---|
| 2751 | else if (nextCUAddr == m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx]) |
---|
| 2752 | { |
---|
| 2753 | // Dependent slice |
---|
| 2754 | pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr ); // to be used in encodeSlice() + context restriction |
---|
| 2755 | pcSlice->setSliceSegmentCurEndCUAddr ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] ); |
---|
| 2756 | |
---|
| 2757 | pcSlice->setNextSliceSegment( true ); |
---|
| 2758 | |
---|
| 2759 | startCUAddrSliceSegmentIdx++; |
---|
| 2760 | } |
---|
[588] | 2761 | #if SVC_EXTENSION |
---|
[313] | 2762 | pcSlice->setNumMotionPredRefLayers(m_pcEncTop->getNumMotionPredRefLayers()); |
---|
| 2763 | #endif |
---|
| 2764 | pcSlice->setRPS(pcPic->getSlice(0)->getRPS()); |
---|
| 2765 | pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx()); |
---|
| 2766 | UInt uiDummyStartCUAddr; |
---|
| 2767 | UInt uiDummyBoundingCUAddr; |
---|
| 2768 | m_pcSliceEncoder->xDetermineStartAndBoundingCUAddr(uiDummyStartCUAddr,uiDummyBoundingCUAddr,pcPic,true); |
---|
| 2769 | |
---|
| 2770 | uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) % pcPic->getNumPartInCU(); |
---|
| 2771 | uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) / pcPic->getNumPartInCU(); |
---|
| 2772 | uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; |
---|
| 2773 | uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; |
---|
[442] | 2774 | |
---|
| 2775 | #if REPN_FORMAT_IN_VPS |
---|
| 2776 | uiWidth = pcSlice->getPicWidthInLumaSamples(); |
---|
| 2777 | uiHeight = pcSlice->getPicHeightInLumaSamples(); |
---|
| 2778 | #else |
---|
[313] | 2779 | uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples(); |
---|
| 2780 | uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples(); |
---|
[442] | 2781 | #endif |
---|
[313] | 2782 | while(uiPosX>=uiWidth||uiPosY>=uiHeight) |
---|
| 2783 | { |
---|
| 2784 | uiInternalAddress--; |
---|
| 2785 | uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; |
---|
| 2786 | uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; |
---|
| 2787 | } |
---|
| 2788 | uiInternalAddress++; |
---|
| 2789 | if(uiInternalAddress==pcPic->getNumPartInCU()) |
---|
| 2790 | { |
---|
| 2791 | uiInternalAddress = 0; |
---|
| 2792 | uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1); |
---|
| 2793 | } |
---|
| 2794 | UInt endAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress); |
---|
| 2795 | if(endAddress<=pcSlice->getSliceSegmentCurStartCUAddr()) |
---|
| 2796 | { |
---|
| 2797 | UInt boundingAddrSlice, boundingAddrSliceSegment; |
---|
| 2798 | boundingAddrSlice = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx]; |
---|
| 2799 | boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx]; |
---|
| 2800 | nextCUAddr = min(boundingAddrSlice, boundingAddrSliceSegment); |
---|
| 2801 | if(pcSlice->isNextSlice()) |
---|
| 2802 | { |
---|
| 2803 | skippedSlice=true; |
---|
| 2804 | } |
---|
| 2805 | continue; |
---|
| 2806 | } |
---|
| 2807 | if(skippedSlice) |
---|
| 2808 | { |
---|
| 2809 | pcSlice->setNextSlice ( true ); |
---|
| 2810 | pcSlice->setNextSliceSegment( false ); |
---|
| 2811 | } |
---|
| 2812 | skippedSlice=false; |
---|
| 2813 | pcSlice->allocSubstreamSizes( iNumSubstreams ); |
---|
| 2814 | for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ ) |
---|
| 2815 | { |
---|
| 2816 | pcSubstreamsOut[ui].clear(); |
---|
| 2817 | } |
---|
| 2818 | |
---|
| 2819 | m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice ); |
---|
| 2820 | m_pcEntropyCoder->resetEntropy (); |
---|
| 2821 | /* start slice NALunit */ |
---|
| 2822 | #if SVC_EXTENSION |
---|
| 2823 | OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), m_layerId ); |
---|
| 2824 | #else |
---|
| 2825 | OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() ); |
---|
| 2826 | #endif |
---|
| 2827 | Bool sliceSegment = (!pcSlice->isNextSlice()); |
---|
| 2828 | if (!sliceSegment) |
---|
| 2829 | { |
---|
| 2830 | uiOneBitstreamPerSliceLength = 0; // start of a new slice |
---|
| 2831 | } |
---|
| 2832 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
[713] | 2833 | |
---|
| 2834 | #if SETTING_NO_OUT_PIC_PRIOR |
---|
[906] | 2835 | pcSlice->setNoRaslOutputFlag(false); |
---|
[713] | 2836 | if (pcSlice->isIRAP()) |
---|
| 2837 | { |
---|
| 2838 | if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP) |
---|
| 2839 | { |
---|
| 2840 | pcSlice->setNoRaslOutputFlag(true); |
---|
| 2841 | } |
---|
| 2842 | //the inference for NoOutputPriorPicsFlag |
---|
[906] | 2843 | // KJS: This cannot happen at the encoder |
---|
[713] | 2844 | if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag()) |
---|
| 2845 | { |
---|
| 2846 | if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) |
---|
| 2847 | { |
---|
| 2848 | pcSlice->setNoOutputPriorPicsFlag(true); |
---|
| 2849 | } |
---|
| 2850 | } |
---|
| 2851 | } |
---|
| 2852 | #endif |
---|
| 2853 | |
---|
[313] | 2854 | tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits(); |
---|
| 2855 | m_pcEntropyCoder->encodeSliceHeader(pcSlice); |
---|
| 2856 | actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting ); |
---|
| 2857 | |
---|
| 2858 | // is it needed? |
---|
| 2859 | { |
---|
| 2860 | if (!sliceSegment) |
---|
| 2861 | { |
---|
| 2862 | pcBitstreamRedirect->writeAlignOne(); |
---|
| 2863 | } |
---|
| 2864 | else |
---|
| 2865 | { |
---|
| 2866 | // We've not completed our slice header info yet, do the alignment later. |
---|
| 2867 | } |
---|
| 2868 | m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC ); |
---|
| 2869 | m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice ); |
---|
| 2870 | m_pcEntropyCoder->resetEntropy (); |
---|
[906] | 2871 | #if WPP_FIX |
---|
| 2872 | for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) |
---|
| 2873 | #else |
---|
[313] | 2874 | for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ ) |
---|
[906] | 2875 | #endif |
---|
[313] | 2876 | { |
---|
| 2877 | m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice ); |
---|
| 2878 | m_pcEntropyCoder->resetEntropy (); |
---|
| 2879 | } |
---|
| 2880 | } |
---|
| 2881 | |
---|
| 2882 | if(pcSlice->isNextSlice()) |
---|
| 2883 | { |
---|
| 2884 | // set entropy coder for writing |
---|
| 2885 | m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC ); |
---|
| 2886 | { |
---|
[906] | 2887 | #if WPP_FIX |
---|
| 2888 | for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) |
---|
| 2889 | #else |
---|
[313] | 2890 | for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ ) |
---|
[906] | 2891 | #endif |
---|
[313] | 2892 | { |
---|
| 2893 | m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice ); |
---|
| 2894 | m_pcEntropyCoder->resetEntropy (); |
---|
| 2895 | } |
---|
| 2896 | pcSbacCoders[0].load(m_pcSbacCoder); |
---|
| 2897 | m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[0], pcSlice ); //ALF is written in substream #0 with CABAC coder #0 (see ALF param encoding below) |
---|
| 2898 | } |
---|
| 2899 | m_pcEntropyCoder->resetEntropy (); |
---|
| 2900 | // File writing |
---|
| 2901 | if (!sliceSegment) |
---|
| 2902 | { |
---|
| 2903 | m_pcEntropyCoder->setBitstream(pcBitstreamRedirect); |
---|
| 2904 | } |
---|
| 2905 | else |
---|
| 2906 | { |
---|
| 2907 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
| 2908 | } |
---|
| 2909 | // for now, override the TILES_DECODER setting in order to write substreams. |
---|
| 2910 | m_pcEntropyCoder->setBitstream ( &pcSubstreamsOut[0] ); |
---|
| 2911 | |
---|
| 2912 | } |
---|
| 2913 | pcSlice->setFinalized(true); |
---|
| 2914 | |
---|
| 2915 | m_pcSbacCoder->load( &pcSbacCoders[0] ); |
---|
| 2916 | |
---|
| 2917 | pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength ); |
---|
[906] | 2918 | pcSlice->setTileLocationCount ( 0 ); |
---|
[313] | 2919 | m_pcSliceEncoder->encodeSlice(pcPic, pcSubstreamsOut); |
---|
| 2920 | |
---|
| 2921 | { |
---|
| 2922 | // Construct the final bitstream by flushing and concatenating substreams. |
---|
| 2923 | // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect; |
---|
| 2924 | UInt* puiSubstreamSizes = pcSlice->getSubstreamSizes(); |
---|
| 2925 | UInt uiTotalCodedSize = 0; // for padding calcs. |
---|
| 2926 | UInt uiNumSubstreamsPerTile = iNumSubstreams; |
---|
| 2927 | if (iNumSubstreams > 1) |
---|
| 2928 | { |
---|
| 2929 | uiNumSubstreamsPerTile /= pcPic->getPicSym()->getNumTiles(); |
---|
| 2930 | } |
---|
| 2931 | for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ ) |
---|
| 2932 | { |
---|
| 2933 | // Flush all substreams -- this includes empty ones. |
---|
| 2934 | // Terminating bit and flush. |
---|
| 2935 | m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice ); |
---|
| 2936 | m_pcEntropyCoder->setBitstream ( &pcSubstreamsOut[ui] ); |
---|
| 2937 | m_pcEntropyCoder->encodeTerminatingBit( 1 ); |
---|
| 2938 | m_pcEntropyCoder->encodeSliceFinish(); |
---|
| 2939 | |
---|
| 2940 | pcSubstreamsOut[ui].writeByteAlignment(); // Byte-alignment in slice_data() at end of sub-stream |
---|
| 2941 | // Byte alignment is necessary between tiles when tiles are independent. |
---|
| 2942 | uiTotalCodedSize += pcSubstreamsOut[ui].getNumberOfWrittenBits(); |
---|
| 2943 | |
---|
| 2944 | Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)&& ((ui+1)%uiNumSubstreamsPerTile == 0); |
---|
[906] | 2945 | #if WPP_FIX |
---|
| 2946 | if (bNextSubstreamInNewTile && !pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ) |
---|
| 2947 | #else |
---|
[313] | 2948 | if (bNextSubstreamInNewTile) |
---|
[906] | 2949 | #endif |
---|
[313] | 2950 | { |
---|
| 2951 | pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3)); |
---|
| 2952 | } |
---|
[906] | 2953 | #if WPP_FIX |
---|
| 2954 | if (ui+1 < iNumSubstreams) |
---|
| 2955 | { |
---|
| 2956 | puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits() + (pcSubstreamsOut[ui].countStartCodeEmulations()<<3); |
---|
| 2957 | } |
---|
| 2958 | #else |
---|
[313] | 2959 | if (ui+1 < pcSlice->getPPS()->getNumSubstreams()) |
---|
| 2960 | { |
---|
| 2961 | puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits() + (pcSubstreamsOut[ui].countStartCodeEmulations()<<3); |
---|
| 2962 | } |
---|
[906] | 2963 | #endif |
---|
[313] | 2964 | } |
---|
| 2965 | |
---|
| 2966 | // Complete the slice header info. |
---|
| 2967 | m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice ); |
---|
| 2968 | m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream); |
---|
[644] | 2969 | #if !POC_RESET_IDC_SIGNALLING |
---|
[313] | 2970 | m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice ); |
---|
[644] | 2971 | #else |
---|
| 2972 | tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits(); |
---|
| 2973 | m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice ); |
---|
| 2974 | actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting ); |
---|
| 2975 | m_pcEntropyCoder->encodeSliceHeaderExtn( pcSlice, actualHeadBits ); |
---|
| 2976 | #endif |
---|
[313] | 2977 | |
---|
| 2978 | // Substreams... |
---|
| 2979 | TComOutputBitstream *pcOut = pcBitstreamRedirect; |
---|
[906] | 2980 | #if WPP_FIX |
---|
| 2981 | Int numZeroSubstreamsAtStartOfSlice = 0; |
---|
| 2982 | Int numSubstreamsToCode = pcSlice->getPPS()->getNumSubstreams(); |
---|
| 2983 | if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) |
---|
| 2984 | { |
---|
| 2985 | Int maxNumParts = pcPic->getNumPartInCU(); |
---|
| 2986 | numZeroSubstreamsAtStartOfSlice = pcPic->getSubstreamForLCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()/maxNumParts, false, pcSlice); |
---|
| 2987 | // 1st line present for WPP. |
---|
| 2988 | numSubstreamsToCode = pcSlice->getNumEntryPointOffsets()+1; |
---|
| 2989 | } |
---|
| 2990 | for ( UInt ui = 0 ; ui < numSubstreamsToCode; ui++ ) |
---|
| 2991 | { |
---|
| 2992 | pcOut->addSubstream(&pcSubstreamsOut[ui+numZeroSubstreamsAtStartOfSlice]); |
---|
| 2993 | } |
---|
| 2994 | #else |
---|
| 2995 | Int offs = 0; |
---|
[313] | 2996 | Int nss = pcSlice->getPPS()->getNumSubstreams(); |
---|
| 2997 | if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) |
---|
| 2998 | { |
---|
| 2999 | // 1st line present for WPP. |
---|
| 3000 | offs = pcSlice->getSliceSegmentCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU(); |
---|
| 3001 | nss = pcSlice->getNumEntryPointOffsets()+1; |
---|
| 3002 | } |
---|
| 3003 | for ( UInt ui = 0 ; ui < nss; ui++ ) |
---|
| 3004 | { |
---|
| 3005 | pcOut->addSubstream(&pcSubstreamsOut[ui+offs]); |
---|
| 3006 | } |
---|
[906] | 3007 | #endif |
---|
[313] | 3008 | } |
---|
| 3009 | |
---|
| 3010 | UInt boundingAddrSlice, boundingAddrSliceSegment; |
---|
| 3011 | boundingAddrSlice = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx]; |
---|
| 3012 | boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx]; |
---|
| 3013 | nextCUAddr = min(boundingAddrSlice, boundingAddrSliceSegment); |
---|
| 3014 | // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it. |
---|
| 3015 | // If current NALU is the last NALU of slice and a NALU was buffered, then (a) Write current NALU (b) Update an write buffered NALU at approproate location in NALU list. |
---|
| 3016 | Bool bNALUAlignedWrittenToList = false; // used to ensure current NALU is not written more than once to the NALU list. |
---|
| 3017 | xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect); |
---|
| 3018 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 3019 | actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8; |
---|
| 3020 | bNALUAlignedWrittenToList = true; |
---|
| 3021 | uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment |
---|
| 3022 | |
---|
| 3023 | if (!bNALUAlignedWrittenToList) |
---|
| 3024 | { |
---|
| 3025 | { |
---|
| 3026 | nalu.m_Bitstream.writeAlignZero(); |
---|
| 3027 | } |
---|
| 3028 | accessUnit.push_back(new NALUnitEBSP(nalu)); |
---|
| 3029 | uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits() + 24; // length of bitstream after byte-alignment + 3 byte startcode 0x000001 |
---|
| 3030 | } |
---|
| 3031 | |
---|
| 3032 | if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) && |
---|
| 3033 | ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && |
---|
| 3034 | ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) |
---|
| 3035 | || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) && |
---|
| 3036 | ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) ) |
---|
| 3037 | { |
---|
| 3038 | UInt numNalus = 0; |
---|
| 3039 | UInt numRBSPBytes = 0; |
---|
| 3040 | for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++) |
---|
| 3041 | { |
---|
| 3042 | UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size()); |
---|
| 3043 | if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI) |
---|
| 3044 | { |
---|
| 3045 | numRBSPBytes += numRBSPBytes_nal; |
---|
| 3046 | numNalus ++; |
---|
| 3047 | } |
---|
| 3048 | } |
---|
| 3049 | accumBitsDU[ pcSlice->getSliceIdx() ] = ( numRBSPBytes << 3 ); |
---|
| 3050 | accumNalsDU[ pcSlice->getSliceIdx() ] = numNalus; // SEI not counted for bit count; hence shouldn't be counted for # of NALUs - only for consistency |
---|
| 3051 | } |
---|
| 3052 | processingState = ENCODE_SLICE; |
---|
| 3053 | } |
---|
| 3054 | break; |
---|
| 3055 | case EXECUTE_INLOOPFILTER: |
---|
| 3056 | { |
---|
| 3057 | // set entropy coder for RD |
---|
| 3058 | m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice ); |
---|
[540] | 3059 | #if HIGHER_LAYER_IRAP_SKIP_FLAG |
---|
| 3060 | if ( pcSlice->getSPS()->getUseSAO() && !( m_pcEncTop->getSkipPictureAtArcSwitch() && m_pcEncTop->getAdaptiveResolutionChange() > 0 && pcSlice->getLayerId() == 1 && pcSlice->getPOC() == m_pcEncTop->getAdaptiveResolutionChange()) ) |
---|
| 3061 | #else |
---|
[313] | 3062 | if ( pcSlice->getSPS()->getUseSAO() ) |
---|
[540] | 3063 | #endif |
---|
[313] | 3064 | { |
---|
| 3065 | m_pcEntropyCoder->resetEntropy(); |
---|
| 3066 | m_pcEntropyCoder->setBitstream( m_pcBitCounter ); |
---|
[540] | 3067 | Bool sliceEnabled[NUM_SAO_COMPONENTS]; |
---|
| 3068 | m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice); |
---|
| 3069 | m_pcSAO->SAOProcess(pcPic |
---|
| 3070 | , sliceEnabled |
---|
| 3071 | , pcPic->getSlice(0)->getLambdas() |
---|
| 3072 | #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK |
---|
| 3073 | , m_pcCfg->getSaoLcuBoundary() |
---|
| 3074 | #endif |
---|
| 3075 | ); |
---|
| 3076 | m_pcSAO->PCMLFDisableProcess(pcPic); |
---|
| 3077 | |
---|
| 3078 | //assign SAO slice header |
---|
| 3079 | for(Int s=0; s< uiNumSlices; s++) |
---|
| 3080 | { |
---|
| 3081 | pcPic->getSlice(s)->setSaoEnabledFlag(sliceEnabled[SAO_Y]); |
---|
| 3082 | assert(sliceEnabled[SAO_Cb] == sliceEnabled[SAO_Cr]); |
---|
| 3083 | pcPic->getSlice(s)->setSaoEnabledFlagChroma(sliceEnabled[SAO_Cb]); |
---|
| 3084 | } |
---|
[313] | 3085 | } |
---|
| 3086 | processingState = ENCODE_SLICE; |
---|
| 3087 | } |
---|
| 3088 | break; |
---|
| 3089 | default: |
---|
| 3090 | { |
---|
| 3091 | printf("Not a supported encoding state\n"); |
---|
| 3092 | assert(0); |
---|
| 3093 | exit(-1); |
---|
| 3094 | } |
---|
| 3095 | } |
---|
| 3096 | } // end iteration over slices |
---|
| 3097 | pcPic->compressMotion(); |
---|
| 3098 | |
---|
| 3099 | //-- For time output for each slice |
---|
| 3100 | Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC; |
---|
| 3101 | |
---|
| 3102 | const Char* digestStr = NULL; |
---|
| 3103 | if (m_pcCfg->getDecodedPictureHashSEIEnabled()) |
---|
| 3104 | { |
---|
| 3105 | /* calculate MD5sum for entire reconstructed picture */ |
---|
| 3106 | SEIDecodedPictureHash sei_recon_picture_digest; |
---|
| 3107 | if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1) |
---|
| 3108 | { |
---|
| 3109 | sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5; |
---|
| 3110 | calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest); |
---|
| 3111 | digestStr = digestToString(sei_recon_picture_digest.digest, 16); |
---|
| 3112 | } |
---|
| 3113 | else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2) |
---|
| 3114 | { |
---|
| 3115 | sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC; |
---|
| 3116 | calcCRC(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest); |
---|
| 3117 | digestStr = digestToString(sei_recon_picture_digest.digest, 2); |
---|
| 3118 | } |
---|
| 3119 | else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3) |
---|
| 3120 | { |
---|
| 3121 | sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM; |
---|
| 3122 | calcChecksum(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest); |
---|
| 3123 | digestStr = digestToString(sei_recon_picture_digest.digest, 4); |
---|
| 3124 | } |
---|
| 3125 | #if SVC_EXTENSION |
---|
| 3126 | OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer(), m_layerId); |
---|
| 3127 | #else |
---|
| 3128 | OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer()); |
---|
| 3129 | #endif |
---|
| 3130 | |
---|
| 3131 | /* write the SEI messages */ |
---|
| 3132 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
[644] | 3133 | #if O0164_MULTI_LAYER_HRD |
---|
| 3134 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 3135 | #else |
---|
[313] | 3136 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, pcSlice->getSPS()); |
---|
[644] | 3137 | #endif |
---|
[313] | 3138 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 3139 | |
---|
| 3140 | accessUnit.insert(accessUnit.end(), new NALUnitEBSP(nalu)); |
---|
| 3141 | } |
---|
| 3142 | if (m_pcCfg->getTemporalLevel0IndexSEIEnabled()) |
---|
| 3143 | { |
---|
| 3144 | SEITemporalLevel0Index sei_temporal_level0_index; |
---|
| 3145 | if (pcSlice->getRapPicFlag()) |
---|
| 3146 | { |
---|
| 3147 | m_tl0Idx = 0; |
---|
| 3148 | m_rapIdx = (m_rapIdx + 1) & 0xFF; |
---|
| 3149 | } |
---|
| 3150 | else |
---|
| 3151 | { |
---|
| 3152 | m_tl0Idx = (m_tl0Idx + (pcSlice->getTLayer() ? 0 : 1)) & 0xFF; |
---|
| 3153 | } |
---|
| 3154 | sei_temporal_level0_index.tl0Idx = m_tl0Idx; |
---|
| 3155 | sei_temporal_level0_index.rapIdx = m_rapIdx; |
---|
| 3156 | |
---|
| 3157 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); |
---|
| 3158 | |
---|
| 3159 | /* write the SEI messages */ |
---|
| 3160 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
[644] | 3161 | #if O0164_MULTI_LAYER_HRD |
---|
| 3162 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 3163 | #else |
---|
[313] | 3164 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, pcSlice->getSPS()); |
---|
[644] | 3165 | #endif |
---|
[313] | 3166 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 3167 | |
---|
| 3168 | /* insert the SEI message NALUnit before any Slice NALUnits */ |
---|
| 3169 | AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice)); |
---|
| 3170 | accessUnit.insert(it, new NALUnitEBSP(nalu)); |
---|
| 3171 | } |
---|
| 3172 | |
---|
| 3173 | xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime ); |
---|
| 3174 | |
---|
[442] | 3175 | //In case of field coding, compute the interlaced PSNR for both fields |
---|
[595] | 3176 | if (isField && ((!pcPic->isTopField() && isTff) || (pcPic->isTopField() && !isTff)) && (pcPic->getPOC()%m_iGopSize != 1)) |
---|
[442] | 3177 | { |
---|
| 3178 | //get complementary top field |
---|
| 3179 | TComPic* pcPicTop; |
---|
| 3180 | TComList<TComPic*>::iterator iterPic = rcListPic.begin(); |
---|
| 3181 | while ((*iterPic)->getPOC() != pcPic->getPOC()-1) |
---|
| 3182 | { |
---|
| 3183 | iterPic ++; |
---|
| 3184 | } |
---|
| 3185 | pcPicTop = *(iterPic); |
---|
| 3186 | xCalculateInterlacedAddPSNR(pcPicTop, pcPic, pcPicTop->getPicYuvRec(), pcPic->getPicYuvRec(), accessUnit, dEncTime ); |
---|
| 3187 | } |
---|
[595] | 3188 | else if (isField && pcPic->getPOC()!= 0 && (pcPic->getPOC()%m_iGopSize == 0)) |
---|
| 3189 | { |
---|
| 3190 | //get complementary bottom field |
---|
| 3191 | TComPic* pcPicBottom; |
---|
| 3192 | TComList<TComPic*>::iterator iterPic = rcListPic.begin(); |
---|
| 3193 | while ((*iterPic)->getPOC() != pcPic->getPOC()+1) |
---|
| 3194 | { |
---|
| 3195 | iterPic ++; |
---|
| 3196 | } |
---|
| 3197 | pcPicBottom = *(iterPic); |
---|
| 3198 | xCalculateInterlacedAddPSNR(pcPic, pcPicBottom, pcPic->getPicYuvRec(), pcPicBottom->getPicYuvRec(), accessUnit, dEncTime ); |
---|
| 3199 | } |
---|
[442] | 3200 | |
---|
[313] | 3201 | if (digestStr) |
---|
| 3202 | { |
---|
| 3203 | if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1) |
---|
| 3204 | { |
---|
| 3205 | printf(" [MD5:%s]", digestStr); |
---|
| 3206 | } |
---|
| 3207 | else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2) |
---|
| 3208 | { |
---|
| 3209 | printf(" [CRC:%s]", digestStr); |
---|
| 3210 | } |
---|
| 3211 | else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3) |
---|
| 3212 | { |
---|
| 3213 | printf(" [Checksum:%s]", digestStr); |
---|
| 3214 | } |
---|
| 3215 | } |
---|
| 3216 | if ( m_pcCfg->getUseRateCtrl() ) |
---|
| 3217 | { |
---|
| 3218 | Double avgQP = m_pcRateCtrl->getRCPic()->calAverageQP(); |
---|
| 3219 | Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda(); |
---|
| 3220 | if ( avgLambda < 0.0 ) |
---|
| 3221 | { |
---|
| 3222 | avgLambda = lambda; |
---|
| 3223 | } |
---|
| 3224 | m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType()); |
---|
| 3225 | m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() ); |
---|
| 3226 | |
---|
| 3227 | m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits ); |
---|
| 3228 | if ( pcSlice->getSliceType() != I_SLICE ) |
---|
| 3229 | { |
---|
| 3230 | m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits ); |
---|
| 3231 | } |
---|
| 3232 | else // for intra picture, the estimated bits are used to update the current status in the GOP |
---|
| 3233 | { |
---|
| 3234 | m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits ); |
---|
| 3235 | } |
---|
| 3236 | } |
---|
| 3237 | |
---|
| 3238 | if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) && |
---|
| 3239 | ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && |
---|
| 3240 | ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) |
---|
| 3241 | || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) ) |
---|
| 3242 | { |
---|
| 3243 | TComVUI *vui = pcSlice->getSPS()->getVuiParameters(); |
---|
| 3244 | TComHRD *hrd = vui->getHrdParameters(); |
---|
| 3245 | |
---|
| 3246 | if( hrd->getSubPicCpbParamsPresentFlag() ) |
---|
| 3247 | { |
---|
| 3248 | Int i; |
---|
| 3249 | UInt64 ui64Tmp; |
---|
| 3250 | UInt uiPrev = 0; |
---|
| 3251 | UInt numDU = ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); |
---|
| 3252 | UInt *pCRD = &pictureTimingSEI.m_duCpbRemovalDelayMinus1[0]; |
---|
| 3253 | UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1; |
---|
| 3254 | |
---|
| 3255 | for( i = 0; i < numDU; i ++ ) |
---|
| 3256 | { |
---|
| 3257 | pictureTimingSEI.m_numNalusInDuMinus1[ i ] = ( i == 0 ) ? ( accumNalsDU[ i ] - 1 ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 ); |
---|
| 3258 | } |
---|
| 3259 | |
---|
| 3260 | if( numDU == 1 ) |
---|
| 3261 | { |
---|
| 3262 | pCRD[ 0 ] = 0; /* don't care */ |
---|
| 3263 | } |
---|
| 3264 | else |
---|
| 3265 | { |
---|
| 3266 | pCRD[ numDU - 1 ] = 0;/* by definition */ |
---|
| 3267 | UInt tmp = 0; |
---|
| 3268 | UInt accum = 0; |
---|
| 3269 | |
---|
| 3270 | for( i = ( numDU - 2 ); i >= 0; i -- ) |
---|
| 3271 | { |
---|
| 3272 | ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ] - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) ); |
---|
| 3273 | if( (UInt)ui64Tmp > maxDiff ) |
---|
| 3274 | { |
---|
| 3275 | tmp ++; |
---|
| 3276 | } |
---|
| 3277 | } |
---|
| 3278 | uiPrev = 0; |
---|
| 3279 | |
---|
| 3280 | UInt flag = 0; |
---|
| 3281 | for( i = ( numDU - 2 ); i >= 0; i -- ) |
---|
| 3282 | { |
---|
| 3283 | flag = 0; |
---|
| 3284 | ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ] - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) ); |
---|
| 3285 | |
---|
| 3286 | if( (UInt)ui64Tmp > maxDiff ) |
---|
| 3287 | { |
---|
| 3288 | if(uiPrev >= maxDiff - tmp) |
---|
| 3289 | { |
---|
| 3290 | ui64Tmp = uiPrev + 1; |
---|
| 3291 | flag = 1; |
---|
| 3292 | } |
---|
| 3293 | else ui64Tmp = maxDiff - tmp + 1; |
---|
| 3294 | } |
---|
| 3295 | pCRD[ i ] = (UInt)ui64Tmp - uiPrev - 1; |
---|
| 3296 | if( (Int)pCRD[ i ] < 0 ) |
---|
| 3297 | { |
---|
| 3298 | pCRD[ i ] = 0; |
---|
| 3299 | } |
---|
| 3300 | else if (tmp > 0 && flag == 1) |
---|
| 3301 | { |
---|
| 3302 | tmp --; |
---|
| 3303 | } |
---|
| 3304 | accum += pCRD[ i ] + 1; |
---|
| 3305 | uiPrev = accum; |
---|
| 3306 | } |
---|
| 3307 | } |
---|
| 3308 | } |
---|
| 3309 | if( m_pcCfg->getPictureTimingSEIEnabled() ) |
---|
| 3310 | { |
---|
| 3311 | { |
---|
| 3312 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer()); |
---|
| 3313 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
[442] | 3314 | pictureTimingSEI.m_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0; |
---|
[644] | 3315 | #if O0164_MULTI_LAYER_HRD |
---|
| 3316 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 3317 | #else |
---|
[313] | 3318 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, pcSlice->getSPS()); |
---|
[644] | 3319 | #endif |
---|
[313] | 3320 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 3321 | UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit); |
---|
| 3322 | UInt offsetPosition = m_activeParameterSetSEIPresentInAU |
---|
| 3323 | + m_bufferingPeriodSEIPresentInAU; // Insert PT SEI after APS and BP SEI |
---|
| 3324 | AccessUnit::iterator it; |
---|
| 3325 | for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++) |
---|
| 3326 | { |
---|
| 3327 | it++; |
---|
| 3328 | } |
---|
| 3329 | accessUnit.insert(it, new NALUnitEBSP(nalu)); |
---|
| 3330 | m_pictureTimingSEIPresentInAU = true; |
---|
| 3331 | } |
---|
| 3332 | if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI |
---|
| 3333 | { |
---|
| 3334 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer()); |
---|
| 3335 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 3336 | scalableNestingSEI.m_nestedSEIs.clear(); |
---|
| 3337 | scalableNestingSEI.m_nestedSEIs.push_back(&pictureTimingSEI); |
---|
[644] | 3338 | #if O0164_MULTI_LAYER_HRD |
---|
| 3339 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 3340 | #else |
---|
[313] | 3341 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, pcSlice->getSPS()); |
---|
[644] | 3342 | #endif |
---|
[313] | 3343 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 3344 | UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit); |
---|
| 3345 | UInt offsetPosition = m_activeParameterSetSEIPresentInAU |
---|
| 3346 | + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU + m_nestedBufferingPeriodSEIPresentInAU; // Insert PT SEI after APS and BP SEI |
---|
| 3347 | AccessUnit::iterator it; |
---|
| 3348 | for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++) |
---|
| 3349 | { |
---|
| 3350 | it++; |
---|
| 3351 | } |
---|
| 3352 | accessUnit.insert(it, new NALUnitEBSP(nalu)); |
---|
| 3353 | m_nestedPictureTimingSEIPresentInAU = true; |
---|
| 3354 | } |
---|
| 3355 | } |
---|
| 3356 | if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() ) |
---|
| 3357 | { |
---|
| 3358 | m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice); |
---|
| 3359 | for( Int i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ ) |
---|
| 3360 | { |
---|
| 3361 | OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer()); |
---|
| 3362 | |
---|
| 3363 | SEIDecodingUnitInfo tempSEI; |
---|
| 3364 | tempSEI.m_decodingUnitIdx = i; |
---|
| 3365 | tempSEI.m_duSptCpbRemovalDelay = pictureTimingSEI.m_duCpbRemovalDelayMinus1[i] + 1; |
---|
| 3366 | tempSEI.m_dpbOutputDuDelayPresentFlag = false; |
---|
| 3367 | tempSEI.m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay; |
---|
| 3368 | |
---|
| 3369 | AccessUnit::iterator it; |
---|
| 3370 | // Insert the first one in the right location, before the first slice |
---|
| 3371 | if(i == 0) |
---|
| 3372 | { |
---|
| 3373 | // Insert before the first slice. |
---|
[644] | 3374 | #if O0164_MULTI_LAYER_HRD |
---|
| 3375 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 3376 | #else |
---|
[313] | 3377 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS()); |
---|
[644] | 3378 | #endif |
---|
[313] | 3379 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 3380 | |
---|
| 3381 | UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit); |
---|
| 3382 | UInt offsetPosition = m_activeParameterSetSEIPresentInAU |
---|
| 3383 | + m_bufferingPeriodSEIPresentInAU |
---|
| 3384 | + m_pictureTimingSEIPresentInAU; // Insert DU info SEI after APS, BP and PT SEI |
---|
| 3385 | for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++) |
---|
| 3386 | { |
---|
| 3387 | it++; |
---|
| 3388 | } |
---|
| 3389 | accessUnit.insert(it, new NALUnitEBSP(nalu)); |
---|
| 3390 | } |
---|
| 3391 | else |
---|
| 3392 | { |
---|
| 3393 | Int ctr; |
---|
| 3394 | // For the second decoding unit onwards we know how many NALUs are present |
---|
| 3395 | for (ctr = 0, it = accessUnit.begin(); it != accessUnit.end(); it++) |
---|
| 3396 | { |
---|
| 3397 | if(ctr == accumNalsDU[ i - 1 ]) |
---|
| 3398 | { |
---|
| 3399 | // Insert before the first slice. |
---|
[644] | 3400 | #if O0164_MULTI_LAYER_HRD |
---|
| 3401 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, m_pcEncTop->getVPS(), pcSlice->getSPS()); |
---|
| 3402 | #else |
---|
[313] | 3403 | m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS()); |
---|
[644] | 3404 | #endif |
---|
[313] | 3405 | writeRBSPTrailingBits(nalu.m_Bitstream); |
---|
| 3406 | |
---|
| 3407 | accessUnit.insert(it, new NALUnitEBSP(nalu)); |
---|
| 3408 | break; |
---|
| 3409 | } |
---|
| 3410 | if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI) |
---|
| 3411 | { |
---|
| 3412 | ctr++; |
---|
| 3413 | } |
---|
| 3414 | } |
---|
| 3415 | } |
---|
| 3416 | } |
---|
| 3417 | } |
---|
| 3418 | } |
---|
| 3419 | xResetNonNestedSEIPresentFlags(); |
---|
| 3420 | xResetNestedSEIPresentFlags(); |
---|
| 3421 | pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut); |
---|
| 3422 | |
---|
| 3423 | #if M0040_ADAPTIVE_RESOLUTION_CHANGE |
---|
| 3424 | pcPicYuvRecOut->setReconstructed(true); |
---|
| 3425 | #endif |
---|
[906] | 3426 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3427 | m_pcEncTop->setFirstPicInLayerDecodedFlag(true); |
---|
| 3428 | #endif |
---|
[313] | 3429 | pcPic->setReconMark ( true ); |
---|
| 3430 | m_bFirst = false; |
---|
| 3431 | m_iNumPicCoded++; |
---|
| 3432 | m_totalCoded ++; |
---|
| 3433 | /* logging: insert a newline at end of picture period */ |
---|
| 3434 | printf("\n"); |
---|
| 3435 | fflush(stdout); |
---|
| 3436 | |
---|
| 3437 | delete[] pcSubstreamsOut; |
---|
[713] | 3438 | |
---|
| 3439 | #if EFFICIENT_FIELD_IRAP |
---|
| 3440 | if(IRAPtoReorder) |
---|
| 3441 | { |
---|
| 3442 | if(swapIRAPForward) |
---|
| 3443 | { |
---|
| 3444 | if(iGOPid == IRAPGOPid) |
---|
| 3445 | { |
---|
| 3446 | iGOPid = IRAPGOPid +1; |
---|
| 3447 | IRAPtoReorder = false; |
---|
| 3448 | } |
---|
| 3449 | else if(iGOPid == IRAPGOPid +1) |
---|
| 3450 | { |
---|
| 3451 | iGOPid --; |
---|
| 3452 | } |
---|
| 3453 | } |
---|
| 3454 | else |
---|
| 3455 | { |
---|
| 3456 | if(iGOPid == IRAPGOPid) |
---|
| 3457 | { |
---|
| 3458 | iGOPid = IRAPGOPid -1; |
---|
| 3459 | } |
---|
| 3460 | else if(iGOPid == IRAPGOPid -1) |
---|
| 3461 | { |
---|
| 3462 | iGOPid = IRAPGOPid; |
---|
| 3463 | IRAPtoReorder = false; |
---|
| 3464 | } |
---|
| 3465 | } |
---|
| 3466 | } |
---|
| 3467 | #endif |
---|
[313] | 3468 | } |
---|
| 3469 | delete pcBitstreamRedirect; |
---|
| 3470 | |
---|
| 3471 | if( accumBitsDU != NULL) delete accumBitsDU; |
---|
| 3472 | if( accumNalsDU != NULL) delete accumNalsDU; |
---|
| 3473 | |
---|
| 3474 | #if SVC_EXTENSION |
---|
[442] | 3475 | assert ( m_iNumPicCoded <= 1 || (isField && iPOCLast == 1) ); |
---|
[313] | 3476 | #else |
---|
[442] | 3477 | assert ( (m_iNumPicCoded == iNumPicRcvd) || (isField && iPOCLast == 1) ); |
---|
[313] | 3478 | #endif |
---|
| 3479 | } |
---|
| 3480 | |
---|
[815] | 3481 | #if POC_RESET_IDC_ENCODER |
---|
| 3482 | Void TEncGOP::determinePocResetIdc(Int const pocCurr, TComSlice *const slice) |
---|
| 3483 | { |
---|
| 3484 | // If one picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 1 or 2 |
---|
| 3485 | // If BL picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 2 |
---|
| 3486 | // If BL picture is IRAP, and another picture is non-IRAP, then the poc_reset_idc is equal to 1 or 2. |
---|
[906] | 3487 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3488 | slice->setPocMsbNeeded(false); |
---|
| 3489 | #endif |
---|
[815] | 3490 | if( slice->getSliceIdx() == 0 ) // First slice - compute, copy for other slices |
---|
| 3491 | { |
---|
| 3492 | Int needReset = false; |
---|
| 3493 | Int resetDueToBL = false; |
---|
| 3494 | if( slice->getVPS()->getMaxLayers() > 1 ) |
---|
| 3495 | { |
---|
| 3496 | // If IRAP is refreshed in this access unit for base layer |
---|
| 3497 | if( (m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 1 || m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2) |
---|
| 3498 | && ( pocCurr % m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshInterval() == 0 ) |
---|
| 3499 | ) |
---|
| 3500 | { |
---|
| 3501 | // Check if the IRAP refresh interval of any layer does not match that of the base layer |
---|
| 3502 | for(Int i = 1; i < slice->getVPS()->getMaxLayers(); i++) |
---|
| 3503 | { |
---|
| 3504 | Bool refreshIntervalFlag = ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 ); |
---|
| 3505 | Bool refreshTypeFlag = ( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() ); |
---|
| 3506 | if( !(refreshIntervalFlag && refreshTypeFlag) ) |
---|
| 3507 | { |
---|
| 3508 | needReset = true; |
---|
| 3509 | resetDueToBL = true; |
---|
| 3510 | break; |
---|
| 3511 | } |
---|
| 3512 | } |
---|
| 3513 | } |
---|
| 3514 | } |
---|
| 3515 | |
---|
| 3516 | if( !needReset )// No need reset due to base layer IRAP |
---|
| 3517 | { |
---|
| 3518 | // Check if EL IDRs results in POC Reset |
---|
| 3519 | for(Int i = 1; i < slice->getVPS()->getMaxLayers() && !needReset; i++) |
---|
| 3520 | { |
---|
| 3521 | Bool idrFlag = ( (m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() == 2) |
---|
| 3522 | && ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 ) |
---|
| 3523 | ); |
---|
| 3524 | for(Int j = 0; j < slice->getVPS()->getMaxLayers(); j++) |
---|
| 3525 | { |
---|
| 3526 | if( j == i ) |
---|
| 3527 | { |
---|
| 3528 | continue; |
---|
| 3529 | } |
---|
| 3530 | Bool idrOtherPicFlag = ( (m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshType() == 2) |
---|
| 3531 | && ( pocCurr % m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshInterval() == 0 ) |
---|
| 3532 | ); |
---|
| 3533 | |
---|
| 3534 | if( idrFlag != idrOtherPicFlag ) |
---|
| 3535 | { |
---|
| 3536 | needReset = true; |
---|
| 3537 | break; |
---|
| 3538 | } |
---|
| 3539 | } |
---|
| 3540 | } |
---|
| 3541 | } |
---|
| 3542 | if( needReset ) |
---|
| 3543 | { |
---|
| 3544 | if( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2 ) // BL IDR refresh, assuming BL picture present |
---|
| 3545 | { |
---|
| 3546 | if( resetDueToBL ) |
---|
| 3547 | { |
---|
| 3548 | slice->setPocResetIdc( 2 ); // Full reset needed |
---|
[906] | 3549 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3550 | if (slice->getVPS()->getVpsPocLsbAlignedFlag() && slice->getVPS()->getNumDirectRefLayers(slice->getLayerId()) == 0) |
---|
| 3551 | { |
---|
| 3552 | slice->setPocMsbNeeded(true); // Force msb writing |
---|
| 3553 | } |
---|
| 3554 | #endif |
---|
[815] | 3555 | } |
---|
| 3556 | else |
---|
| 3557 | { |
---|
| 3558 | slice->setPocResetIdc( 1 ); // Due to IDR in EL |
---|
| 3559 | } |
---|
| 3560 | } |
---|
| 3561 | else |
---|
| 3562 | { |
---|
| 3563 | slice->setPocResetIdc( 1 ); // Only MSB reset |
---|
| 3564 | } |
---|
| 3565 | |
---|
| 3566 | // Start a new POC reset period |
---|
| 3567 | if (m_layerId == 0) // Assuming BL picture is always present at encoder; for other AU structures, need to change this |
---|
| 3568 | { |
---|
| 3569 | Int periodId = rand() % 64; |
---|
| 3570 | m_lastPocPeriodId = (periodId == m_lastPocPeriodId) ? (periodId + 1) % 64 : periodId ; |
---|
[906] | 3571 | |
---|
| 3572 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3573 | for (UInt i = 0; i < MAX_LAYERS; i++) |
---|
| 3574 | { |
---|
| 3575 | m_ppcTEncTop[i]->setPocDecrementedInDPBFlag(false); |
---|
| 3576 | } |
---|
| 3577 | #endif |
---|
[815] | 3578 | } |
---|
| 3579 | else |
---|
| 3580 | { |
---|
| 3581 | m_lastPocPeriodId = m_ppcTEncTop[0]->getGOPEncoder()->getLastPocPeriodId(); |
---|
| 3582 | } |
---|
| 3583 | slice->setPocResetPeriodId(m_lastPocPeriodId); |
---|
| 3584 | } |
---|
| 3585 | else |
---|
| 3586 | { |
---|
| 3587 | slice->setPocResetIdc( 0 ); |
---|
| 3588 | } |
---|
| 3589 | } |
---|
| 3590 | } |
---|
| 3591 | |
---|
| 3592 | Void TEncGOP::updatePocValuesOfPics(Int const pocCurr, TComSlice *const slice) |
---|
| 3593 | { |
---|
[906] | 3594 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3595 | UInt affectedLayerList[MAX_NUM_LAYER_IDS]; |
---|
| 3596 | Int numAffectedLayers; |
---|
[815] | 3597 | |
---|
[906] | 3598 | affectedLayerList[0] = m_layerId; |
---|
| 3599 | numAffectedLayers = 1; |
---|
| 3600 | |
---|
| 3601 | if (m_pcEncTop->getVPS()->getVpsPocLsbAlignedFlag()) |
---|
| 3602 | { |
---|
| 3603 | for (UInt j = 0; j < m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId); j++) |
---|
| 3604 | { |
---|
| 3605 | affectedLayerList[j + 1] = m_pcEncTop->getVPS()->getPredictedLayerId(m_layerId, j); |
---|
| 3606 | } |
---|
| 3607 | numAffectedLayers = m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId) + 1; |
---|
| 3608 | } |
---|
| 3609 | #endif |
---|
| 3610 | |
---|
[815] | 3611 | Int pocAdjustValue = pocCurr - m_pcEncTop->getPocAdjustmentValue(); |
---|
| 3612 | |
---|
| 3613 | // New POC reset period |
---|
| 3614 | Int maxPocLsb, pocLsbVal, pocMsbDelta, pocLsbDelta, deltaPocVal; |
---|
| 3615 | |
---|
| 3616 | maxPocLsb = 1 << slice->getSPS()->getBitsForPOC(); |
---|
[906] | 3617 | |
---|
| 3618 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3619 | Int adjustedPocValue = pocCurr; |
---|
| 3620 | |
---|
| 3621 | if (m_pcEncTop->getFirstPicInLayerDecodedFlag()) |
---|
| 3622 | { |
---|
| 3623 | #endif |
---|
| 3624 | |
---|
[815] | 3625 | pocLsbVal = (slice->getPocResetIdc() == 3) |
---|
| 3626 | ? slice->getPocLsbVal() |
---|
| 3627 | : pocAdjustValue % maxPocLsb; |
---|
| 3628 | pocMsbDelta = pocAdjustValue - pocLsbVal; |
---|
| 3629 | pocLsbDelta = (slice->getPocResetIdc() == 2 || ( slice->getPocResetIdc() == 3 && slice->getFullPocResetFlag() )) |
---|
| 3630 | ? pocLsbVal |
---|
| 3631 | : 0; |
---|
| 3632 | deltaPocVal = pocMsbDelta + pocLsbDelta; |
---|
[906] | 3633 | |
---|
| 3634 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3635 | Int origDeltaPocVal = deltaPocVal; // original value needed when updating POC adjustment value |
---|
| 3636 | |
---|
| 3637 | if (slice->getPocMsbNeeded()) // IDR picture in base layer, non-IDR picture in other layers, poc_lsb_aligned_flag = 1 |
---|
| 3638 | { |
---|
| 3639 | if (slice->getLayerId() == 0) |
---|
| 3640 | { |
---|
| 3641 | Int highestPoc = INT_MIN; |
---|
| 3642 | // Find greatest POC in DPB for layer 0 |
---|
| 3643 | for (TComList<TComPic*>::iterator iterPic = m_pcEncTop->getListPic()->begin(); iterPic != m_pcEncTop->getListPic()->end(); ++iterPic) |
---|
| 3644 | { |
---|
| 3645 | TComPic *dpbPic = *iterPic; |
---|
| 3646 | if (dpbPic->getReconMark() && dpbPic->getLayerId() == 0 && dpbPic->getPOC() > highestPoc) |
---|
| 3647 | { |
---|
| 3648 | highestPoc = dpbPic->getPOC(); |
---|
| 3649 | } |
---|
| 3650 | } |
---|
| 3651 | deltaPocVal = (highestPoc - (highestPoc & (maxPocLsb - 1))) + 1*maxPocLsb; |
---|
| 3652 | m_pcEncTop->setCurrPocMsb(deltaPocVal); |
---|
| 3653 | } |
---|
| 3654 | else |
---|
| 3655 | { |
---|
| 3656 | deltaPocVal = m_ppcTEncTop[0]->getCurrPocMsb(); // copy from base layer |
---|
| 3657 | } |
---|
| 3658 | slice->setPocMsbVal(deltaPocVal); |
---|
| 3659 | } |
---|
| 3660 | #endif |
---|
| 3661 | |
---|
| 3662 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3663 | for (UInt layerIdx = 0; layerIdx < numAffectedLayers; layerIdx++) |
---|
| 3664 | { |
---|
| 3665 | if (!m_ppcTEncTop[affectedLayerList[layerIdx]]->getPocDecrementedInDPBFlag()) |
---|
| 3666 | { |
---|
| 3667 | m_ppcTEncTop[affectedLayerList[layerIdx]]->setPocDecrementedInDPBFlag(true); |
---|
| 3668 | |
---|
| 3669 | // Decrement value of associatedIrapPoc of the TEncGop object |
---|
| 3670 | m_ppcTEncTop[affectedLayerList[layerIdx]]->getGOPEncoder()->m_associatedIRAPPOC -= deltaPocVal; |
---|
| 3671 | |
---|
| 3672 | // Decrememnt the value of m_pocCRA |
---|
| 3673 | m_ppcTEncTop[affectedLayerList[layerIdx]]->getGOPEncoder()->m_pocCRA -= deltaPocVal; |
---|
| 3674 | |
---|
| 3675 | TComList<TComPic*>::iterator iterPic = m_ppcTEncTop[affectedLayerList[layerIdx]]->getListPic()->begin(); |
---|
| 3676 | while (iterPic != m_ppcTEncTop[affectedLayerList[layerIdx]]->getListPic()->end()) |
---|
| 3677 | #else |
---|
[815] | 3678 | // Decrement value of associatedIrapPoc of the TEncGop object |
---|
| 3679 | this->m_associatedIRAPPOC -= deltaPocVal; |
---|
| 3680 | |
---|
| 3681 | // Decrememnt the value of m_pocCRA |
---|
| 3682 | this->m_pocCRA -= deltaPocVal; |
---|
| 3683 | |
---|
| 3684 | // Iterate through all pictures in the DPB |
---|
| 3685 | TComList<TComPic*>::iterator iterPic = getListPic()->begin(); |
---|
| 3686 | while( iterPic != getListPic()->end() ) |
---|
[906] | 3687 | #endif |
---|
[815] | 3688 | { |
---|
| 3689 | TComPic *dpbPic = *iterPic; |
---|
| 3690 | |
---|
| 3691 | if( dpbPic->getReconMark() ) |
---|
| 3692 | { |
---|
| 3693 | for(Int i = dpbPic->getNumAllocatedSlice() - 1; i >= 0; i--) |
---|
| 3694 | { |
---|
| 3695 | TComSlice *dpbPicSlice = dpbPic->getSlice( i ); |
---|
| 3696 | TComReferencePictureSet *dpbPicRps = dpbPicSlice->getRPS(); |
---|
| 3697 | |
---|
| 3698 | // Decrement POC of slice |
---|
| 3699 | dpbPicSlice->setPOC( dpbPicSlice->getPOC() - deltaPocVal ); |
---|
| 3700 | |
---|
| 3701 | // Decrement POC value stored in the RPS of each such slice |
---|
| 3702 | for( Int j = dpbPicRps->getNumberOfPictures() - 1; j >= 0; j-- ) |
---|
| 3703 | { |
---|
| 3704 | dpbPicRps->setPOC( j, dpbPicRps->getPOC(j) - deltaPocVal ); |
---|
| 3705 | } |
---|
| 3706 | |
---|
| 3707 | // Decrement value of refPOC |
---|
| 3708 | dpbPicSlice->decrementRefPocValues( deltaPocVal ); |
---|
| 3709 | |
---|
| 3710 | // Update value of associatedIrapPoc of each slice |
---|
| 3711 | dpbPicSlice->setAssociatedIRAPPOC( dpbPicSlice->getAssociatedIRAPPOC() - deltaPocVal ); |
---|
[906] | 3712 | |
---|
| 3713 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3714 | if (slice->getPocMsbNeeded()) |
---|
| 3715 | { |
---|
| 3716 | // this delta value is needed when computing delta POCs in reference picture set initialization |
---|
| 3717 | dpbPicSlice->setPocResetDeltaPoc(dpbPicSlice->getPocResetDeltaPoc() + (deltaPocVal - pocLsbVal)); |
---|
| 3718 | } |
---|
| 3719 | #endif |
---|
[815] | 3720 | } |
---|
| 3721 | } |
---|
| 3722 | iterPic++; |
---|
| 3723 | } |
---|
[906] | 3724 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3725 | } |
---|
| 3726 | } |
---|
| 3727 | #endif |
---|
| 3728 | |
---|
[815] | 3729 | // Actual POC value before reset |
---|
[906] | 3730 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3731 | adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue(); |
---|
| 3732 | #else |
---|
[815] | 3733 | Int adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue(); |
---|
[906] | 3734 | #endif |
---|
[815] | 3735 | |
---|
| 3736 | // Set MSB value before reset |
---|
| 3737 | Int tempLsbVal = adjustedPocValue & (maxPocLsb - 1); |
---|
[906] | 3738 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3739 | if (!slice->getPocMsbNeeded()) // set poc msb normally if special msb handling is not needed |
---|
| 3740 | { |
---|
| 3741 | #endif |
---|
| 3742 | slice->setPocMsbVal(adjustedPocValue - tempLsbVal); |
---|
| 3743 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3744 | } |
---|
| 3745 | #endif |
---|
[815] | 3746 | |
---|
| 3747 | // Set LSB value before reset - this is needed in the case of resetIdc = 2 |
---|
| 3748 | slice->setPicOrderCntLsb( tempLsbVal ); |
---|
| 3749 | |
---|
| 3750 | // Cumulative delta |
---|
[906] | 3751 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3752 | deltaPocVal = origDeltaPocVal; // restore deltaPoc for correct adjustment value update |
---|
| 3753 | #endif |
---|
[815] | 3754 | m_pcEncTop->setPocAdjustmentValue( m_pcEncTop->getPocAdjustmentValue() + deltaPocVal ); |
---|
| 3755 | |
---|
[906] | 3756 | #if P0297_VPS_POC_LSB_ALIGNED_FLAG |
---|
| 3757 | } |
---|
| 3758 | #endif |
---|
| 3759 | |
---|
[815] | 3760 | // New LSB value, after reset |
---|
| 3761 | adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue(); |
---|
| 3762 | Int newLsbVal = adjustedPocValue & (maxPocLsb - 1); |
---|
| 3763 | |
---|
| 3764 | // Set value of POC current picture after RESET |
---|
| 3765 | if( slice->getPocResetIdc() == 1 ) |
---|
| 3766 | { |
---|
| 3767 | slice->setPOC( newLsbVal ); |
---|
| 3768 | } |
---|
| 3769 | else if( slice->getPocResetIdc() == 2 ) |
---|
| 3770 | { |
---|
| 3771 | slice->setPOC( 0 ); |
---|
| 3772 | } |
---|
| 3773 | else if( slice->getPocResetIdc() == 3 ) |
---|
| 3774 | { |
---|
| 3775 | Int picOrderCntMsb = slice->getCurrMsb( newLsbVal, |
---|
| 3776 | slice->getFullPocResetFlag() ? 0 : slice->getPocLsbVal(), |
---|
| 3777 | 0, |
---|
| 3778 | maxPocLsb ); |
---|
| 3779 | slice->setPOC( picOrderCntMsb + newLsbVal ); |
---|
| 3780 | } |
---|
| 3781 | else |
---|
| 3782 | { |
---|
| 3783 | assert(0); |
---|
| 3784 | } |
---|
| 3785 | } |
---|
| 3786 | #endif |
---|
| 3787 | |
---|
| 3788 | |
---|
[313] | 3789 | #if !SVC_EXTENSION |
---|
[442] | 3790 | Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField) |
---|
[313] | 3791 | { |
---|
| 3792 | assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic()); |
---|
| 3793 | |
---|
| 3794 | |
---|
| 3795 | //--CFG_KDY |
---|
[442] | 3796 | if(isField) |
---|
| 3797 | { |
---|
| 3798 | m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() * 2); |
---|
| 3799 | m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() * 2); |
---|
| 3800 | m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() * 2); |
---|
| 3801 | m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() * 2); |
---|
| 3802 | } |
---|
| 3803 | else |
---|
| 3804 | { |
---|
| 3805 | m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() ); |
---|
| 3806 | m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() ); |
---|
| 3807 | m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() ); |
---|
| 3808 | m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() ); |
---|
| 3809 | } |
---|
[313] | 3810 | |
---|
| 3811 | //-- all |
---|
| 3812 | printf( "\n\nSUMMARY --------------------------------------------------------\n" ); |
---|
| 3813 | m_gcAnalyzeAll.printOut('a'); |
---|
| 3814 | |
---|
| 3815 | printf( "\n\nI Slices--------------------------------------------------------\n" ); |
---|
| 3816 | m_gcAnalyzeI.printOut('i'); |
---|
| 3817 | |
---|
| 3818 | printf( "\n\nP Slices--------------------------------------------------------\n" ); |
---|
| 3819 | m_gcAnalyzeP.printOut('p'); |
---|
| 3820 | |
---|
| 3821 | printf( "\n\nB Slices--------------------------------------------------------\n" ); |
---|
| 3822 | m_gcAnalyzeB.printOut('b'); |
---|
| 3823 | |
---|
| 3824 | #if _SUMMARY_OUT_ |
---|
| 3825 | m_gcAnalyzeAll.printSummaryOut(); |
---|
| 3826 | #endif |
---|
| 3827 | #if _SUMMARY_PIC_ |
---|
| 3828 | m_gcAnalyzeI.printSummary('I'); |
---|
| 3829 | m_gcAnalyzeP.printSummary('P'); |
---|
| 3830 | m_gcAnalyzeB.printSummary('B'); |
---|
| 3831 | #endif |
---|
| 3832 | |
---|
[442] | 3833 | if(isField) |
---|
| 3834 | { |
---|
| 3835 | //-- interlaced summary |
---|
| 3836 | m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate()); |
---|
| 3837 | printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" ); |
---|
| 3838 | m_gcAnalyzeAll_in.printOutInterlaced('a', m_gcAnalyzeAll.getBits()); |
---|
| 3839 | |
---|
| 3840 | #if _SUMMARY_OUT_ |
---|
| 3841 | m_gcAnalyzeAll_in.printSummaryOutInterlaced(); |
---|
| 3842 | #endif |
---|
| 3843 | } |
---|
| 3844 | |
---|
[313] | 3845 | printf("\nRVM: %.3lf\n" , xCalculateRVM()); |
---|
| 3846 | } |
---|
| 3847 | #endif |
---|
| 3848 | |
---|
| 3849 | Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits ) |
---|
| 3850 | { |
---|
| 3851 | TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx()); |
---|
| 3852 | Bool bCalcDist = false; |
---|
| 3853 | m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag()); |
---|
| 3854 | m_pcLoopFilter->loopFilterPic( pcPic ); |
---|
| 3855 | |
---|
| 3856 | m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice ); |
---|
| 3857 | m_pcEntropyCoder->resetEntropy (); |
---|
| 3858 | m_pcEntropyCoder->setBitstream ( m_pcBitCounter ); |
---|
| 3859 | m_pcEntropyCoder->resetEntropy (); |
---|
| 3860 | ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits(); |
---|
| 3861 | |
---|
| 3862 | if (!bCalcDist) |
---|
| 3863 | ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec()); |
---|
| 3864 | } |
---|
| 3865 | |
---|
| 3866 | // ==================================================================================================================== |
---|
| 3867 | // Protected member functions |
---|
| 3868 | // ==================================================================================================================== |
---|
| 3869 | |
---|
[442] | 3870 | |
---|
| 3871 | Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, Bool isField ) |
---|
| 3872 | { |
---|
| 3873 | assert( iNumPicRcvd > 0 ); |
---|
| 3874 | // Exception for the first frames |
---|
| 3875 | if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField && (iPOCLast == 0)) ) |
---|
| 3876 | { |
---|
| 3877 | m_iGopSize = 1; |
---|
| 3878 | } |
---|
| 3879 | else |
---|
| 3880 | { |
---|
| 3881 | m_iGopSize = m_pcCfg->getGOPSize(); |
---|
| 3882 | } |
---|
| 3883 | assert (m_iGopSize > 0); |
---|
| 3884 | |
---|
| 3885 | return; |
---|
| 3886 | } |
---|
| 3887 | |
---|
[313] | 3888 | Void TEncGOP::xGetBuffer( TComList<TComPic*>& rcListPic, |
---|
| 3889 | TComList<TComPicYuv*>& rcListPicYuvRecOut, |
---|
| 3890 | Int iNumPicRcvd, |
---|
| 3891 | Int iTimeOffset, |
---|
| 3892 | TComPic*& rpcPic, |
---|
| 3893 | TComPicYuv*& rpcPicYuvRecOut, |
---|
[442] | 3894 | Int pocCurr, |
---|
| 3895 | Bool isField) |
---|
[313] | 3896 | { |
---|
| 3897 | Int i; |
---|
| 3898 | // Rec. output |
---|
| 3899 | TComList<TComPicYuv*>::iterator iterPicYuvRec = rcListPicYuvRecOut.end(); |
---|
[442] | 3900 | |
---|
| 3901 | if (isField) |
---|
[313] | 3902 | { |
---|
[442] | 3903 | for ( i = 0; i < ( (pocCurr == 0 ) || (pocCurr == 1 ) ? (iNumPicRcvd - iTimeOffset + 1) : (iNumPicRcvd - iTimeOffset + 2) ); i++ ) |
---|
| 3904 | { |
---|
| 3905 | iterPicYuvRec--; |
---|
| 3906 | } |
---|
[313] | 3907 | } |
---|
[442] | 3908 | else |
---|
| 3909 | { |
---|
| 3910 | for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ ) |
---|
| 3911 | { |
---|
| 3912 | iterPicYuvRec--; |
---|
| 3913 | } |
---|
[540] | 3914 | |
---|
[442] | 3915 | } |
---|
[313] | 3916 | |
---|
[442] | 3917 | if (isField) |
---|
| 3918 | { |
---|
| 3919 | if(pocCurr == 1) |
---|
| 3920 | { |
---|
| 3921 | iterPicYuvRec++; |
---|
| 3922 | } |
---|
| 3923 | } |
---|
[313] | 3924 | rpcPicYuvRecOut = *(iterPicYuvRec); |
---|
| 3925 | |
---|
| 3926 | // Current pic. |
---|
| 3927 | TComList<TComPic*>::iterator iterPic = rcListPic.begin(); |
---|
| 3928 | while (iterPic != rcListPic.end()) |
---|
| 3929 | { |
---|
| 3930 | rpcPic = *(iterPic); |
---|
| 3931 | rpcPic->setCurrSliceIdx(0); |
---|
| 3932 | if (rpcPic->getPOC() == pocCurr) |
---|
| 3933 | { |
---|
| 3934 | break; |
---|
| 3935 | } |
---|
| 3936 | iterPic++; |
---|
| 3937 | } |
---|
| 3938 | |
---|
| 3939 | assert( rpcPic != NULL ); |
---|
| 3940 | assert( rpcPic->getPOC() == pocCurr ); |
---|
| 3941 | |
---|
| 3942 | return; |
---|
| 3943 | } |
---|
| 3944 | |
---|
| 3945 | UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1) |
---|
| 3946 | { |
---|
| 3947 | Int x, y; |
---|
| 3948 | Pel* pSrc0 = pcPic0 ->getLumaAddr(); |
---|
| 3949 | Pel* pSrc1 = pcPic1 ->getLumaAddr(); |
---|
| 3950 | UInt uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthY-8); |
---|
| 3951 | Int iTemp; |
---|
| 3952 | |
---|
| 3953 | Int iStride = pcPic0->getStride(); |
---|
| 3954 | Int iWidth = pcPic0->getWidth(); |
---|
| 3955 | Int iHeight = pcPic0->getHeight(); |
---|
| 3956 | |
---|
| 3957 | UInt64 uiTotalDiff = 0; |
---|
| 3958 | |
---|
| 3959 | for( y = 0; y < iHeight; y++ ) |
---|
| 3960 | { |
---|
| 3961 | for( x = 0; x < iWidth; x++ ) |
---|
| 3962 | { |
---|
| 3963 | iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift; |
---|
| 3964 | } |
---|
| 3965 | pSrc0 += iStride; |
---|
| 3966 | pSrc1 += iStride; |
---|
| 3967 | } |
---|
| 3968 | |
---|
| 3969 | uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthC-8); |
---|
| 3970 | iHeight >>= 1; |
---|
| 3971 | iWidth >>= 1; |
---|
| 3972 | iStride >>= 1; |
---|
| 3973 | |
---|
| 3974 | pSrc0 = pcPic0->getCbAddr(); |
---|
| 3975 | pSrc1 = pcPic1->getCbAddr(); |
---|
| 3976 | |
---|
| 3977 | for( y = 0; y < iHeight; y++ ) |
---|
| 3978 | { |
---|
| 3979 | for( x = 0; x < iWidth; x++ ) |
---|
| 3980 | { |
---|
| 3981 | iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift; |
---|
| 3982 | } |
---|
| 3983 | pSrc0 += iStride; |
---|
| 3984 | pSrc1 += iStride; |
---|
| 3985 | } |
---|
| 3986 | |
---|
| 3987 | pSrc0 = pcPic0->getCrAddr(); |
---|
| 3988 | pSrc1 = pcPic1->getCrAddr(); |
---|
| 3989 | |
---|
| 3990 | for( y = 0; y < iHeight; y++ ) |
---|
| 3991 | { |
---|
| 3992 | for( x = 0; x < iWidth; x++ ) |
---|
| 3993 | { |
---|
| 3994 | iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift; |
---|
| 3995 | } |
---|
| 3996 | pSrc0 += iStride; |
---|
| 3997 | pSrc1 += iStride; |
---|
| 3998 | } |
---|
| 3999 | |
---|
| 4000 | return uiTotalDiff; |
---|
| 4001 | } |
---|
| 4002 | |
---|
| 4003 | #if VERBOSE_RATE |
---|
| 4004 | static const Char* nalUnitTypeToString(NalUnitType type) |
---|
| 4005 | { |
---|
| 4006 | switch (type) |
---|
| 4007 | { |
---|
[442] | 4008 | case NAL_UNIT_CODED_SLICE_TRAIL_R: return "TRAIL_R"; |
---|
| 4009 | case NAL_UNIT_CODED_SLICE_TRAIL_N: return "TRAIL_N"; |
---|
[540] | 4010 | case NAL_UNIT_CODED_SLICE_TSA_R: return "TSA_R"; |
---|
[442] | 4011 | case NAL_UNIT_CODED_SLICE_TSA_N: return "TSA_N"; |
---|
| 4012 | case NAL_UNIT_CODED_SLICE_STSA_R: return "STSA_R"; |
---|
| 4013 | case NAL_UNIT_CODED_SLICE_STSA_N: return "STSA_N"; |
---|
[313] | 4014 | case NAL_UNIT_CODED_SLICE_BLA_W_LP: return "BLA_W_LP"; |
---|
| 4015 | case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL"; |
---|
[442] | 4016 | case NAL_UNIT_CODED_SLICE_BLA_N_LP: return "BLA_N_LP"; |
---|
[313] | 4017 | case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL"; |
---|
[442] | 4018 | case NAL_UNIT_CODED_SLICE_IDR_N_LP: return "IDR_N_LP"; |
---|
| 4019 | case NAL_UNIT_CODED_SLICE_CRA: return "CRA"; |
---|
[313] | 4020 | case NAL_UNIT_CODED_SLICE_RADL_R: return "RADL_R"; |
---|
[713] | 4021 | case NAL_UNIT_CODED_SLICE_RADL_N: return "RADL_N"; |
---|
[313] | 4022 | case NAL_UNIT_CODED_SLICE_RASL_R: return "RASL_R"; |
---|
[713] | 4023 | case NAL_UNIT_CODED_SLICE_RASL_N: return "RASL_N"; |
---|
[442] | 4024 | case NAL_UNIT_VPS: return "VPS"; |
---|
| 4025 | case NAL_UNIT_SPS: return "SPS"; |
---|
| 4026 | case NAL_UNIT_PPS: return "PPS"; |
---|
| 4027 | case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD"; |
---|
| 4028 | case NAL_UNIT_EOS: return "EOS"; |
---|
| 4029 | case NAL_UNIT_EOB: return "EOB"; |
---|
| 4030 | case NAL_UNIT_FILLER_DATA: return "FILLER"; |
---|
[313] | 4031 | case NAL_UNIT_PREFIX_SEI: return "SEI"; |
---|
| 4032 | case NAL_UNIT_SUFFIX_SEI: return "SEI"; |
---|
[442] | 4033 | default: return "UNK"; |
---|
[313] | 4034 | } |
---|
| 4035 | } |
---|
| 4036 | #endif |
---|
| 4037 | |
---|
| 4038 | Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime ) |
---|
| 4039 | { |
---|
| 4040 | Int x, y; |
---|
| 4041 | UInt64 uiSSDY = 0; |
---|
| 4042 | UInt64 uiSSDU = 0; |
---|
| 4043 | UInt64 uiSSDV = 0; |
---|
| 4044 | |
---|
| 4045 | Double dYPSNR = 0.0; |
---|
| 4046 | Double dUPSNR = 0.0; |
---|
| 4047 | Double dVPSNR = 0.0; |
---|
| 4048 | |
---|
| 4049 | //===== calculate PSNR ===== |
---|
| 4050 | Pel* pOrg = pcPic ->getPicYuvOrg()->getLumaAddr(); |
---|
| 4051 | Pel* pRec = pcPicD->getLumaAddr(); |
---|
| 4052 | Int iStride = pcPicD->getStride(); |
---|
| 4053 | |
---|
| 4054 | Int iWidth; |
---|
| 4055 | Int iHeight; |
---|
| 4056 | |
---|
| 4057 | iWidth = pcPicD->getWidth () - m_pcEncTop->getPad(0); |
---|
| 4058 | iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1); |
---|
| 4059 | |
---|
| 4060 | Int iSize = iWidth*iHeight; |
---|
| 4061 | |
---|
| 4062 | for( y = 0; y < iHeight; y++ ) |
---|
| 4063 | { |
---|
| 4064 | for( x = 0; x < iWidth; x++ ) |
---|
| 4065 | { |
---|
| 4066 | Int iDiff = (Int)( pOrg[x] - pRec[x] ); |
---|
| 4067 | uiSSDY += iDiff * iDiff; |
---|
| 4068 | } |
---|
| 4069 | pOrg += iStride; |
---|
| 4070 | pRec += iStride; |
---|
| 4071 | } |
---|
| 4072 | |
---|
| 4073 | iHeight >>= 1; |
---|
| 4074 | iWidth >>= 1; |
---|
| 4075 | iStride >>= 1; |
---|
| 4076 | pOrg = pcPic ->getPicYuvOrg()->getCbAddr(); |
---|
| 4077 | pRec = pcPicD->getCbAddr(); |
---|
| 4078 | |
---|
| 4079 | for( y = 0; y < iHeight; y++ ) |
---|
| 4080 | { |
---|
| 4081 | for( x = 0; x < iWidth; x++ ) |
---|
| 4082 | { |
---|
| 4083 | Int iDiff = (Int)( pOrg[x] - pRec[x] ); |
---|
| 4084 | uiSSDU += iDiff * iDiff; |
---|
| 4085 | } |
---|
| 4086 | pOrg += iStride; |
---|
| 4087 | pRec += iStride; |
---|
| 4088 | } |
---|
| 4089 | |
---|
| 4090 | pOrg = pcPic ->getPicYuvOrg()->getCrAddr(); |
---|
| 4091 | pRec = pcPicD->getCrAddr(); |
---|
| 4092 | |
---|
| 4093 | for( y = 0; y < iHeight; y++ ) |
---|
| 4094 | { |
---|
| 4095 | for( x = 0; x < iWidth; x++ ) |
---|
| 4096 | { |
---|
| 4097 | Int iDiff = (Int)( pOrg[x] - pRec[x] ); |
---|
| 4098 | uiSSDV += iDiff * iDiff; |
---|
| 4099 | } |
---|
| 4100 | pOrg += iStride; |
---|
| 4101 | pRec += iStride; |
---|
| 4102 | } |
---|
| 4103 | |
---|
| 4104 | Int maxvalY = 255 << (g_bitDepthY-8); |
---|
| 4105 | Int maxvalC = 255 << (g_bitDepthC-8); |
---|
| 4106 | Double fRefValueY = (Double) maxvalY * maxvalY * iSize; |
---|
| 4107 | Double fRefValueC = (Double) maxvalC * maxvalC * iSize / 4.0; |
---|
| 4108 | dYPSNR = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 ); |
---|
| 4109 | dUPSNR = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 ); |
---|
| 4110 | dVPSNR = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 ); |
---|
| 4111 | |
---|
| 4112 | /* calculate the size of the access unit, excluding: |
---|
| 4113 | * - any AnnexB contributions (start_code_prefix, zero_byte, etc.,) |
---|
| 4114 | * - SEI NAL units |
---|
| 4115 | */ |
---|
| 4116 | UInt numRBSPBytes = 0; |
---|
| 4117 | for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++) |
---|
| 4118 | { |
---|
| 4119 | UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size()); |
---|
| 4120 | #if VERBOSE_RATE |
---|
| 4121 | printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal); |
---|
| 4122 | #endif |
---|
| 4123 | if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI) |
---|
| 4124 | { |
---|
| 4125 | numRBSPBytes += numRBSPBytes_nal; |
---|
| 4126 | } |
---|
| 4127 | } |
---|
| 4128 | |
---|
| 4129 | UInt uibits = numRBSPBytes * 8; |
---|
| 4130 | m_vRVM_RP.push_back( uibits ); |
---|
| 4131 | |
---|
| 4132 | //===== add PSNR ===== |
---|
| 4133 | #if SVC_EXTENSION |
---|
| 4134 | m_gcAnalyzeAll[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits); |
---|
| 4135 | TComSlice* pcSlice = pcPic->getSlice(0); |
---|
| 4136 | if (pcSlice->isIntra()) |
---|
| 4137 | { |
---|
| 4138 | m_gcAnalyzeI[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits); |
---|
| 4139 | } |
---|
| 4140 | if (pcSlice->isInterP()) |
---|
| 4141 | { |
---|
| 4142 | m_gcAnalyzeP[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits); |
---|
| 4143 | } |
---|
| 4144 | if (pcSlice->isInterB()) |
---|
| 4145 | { |
---|
| 4146 | m_gcAnalyzeB[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits); |
---|
| 4147 | } |
---|
| 4148 | #else |
---|
| 4149 | m_gcAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits); |
---|
| 4150 | TComSlice* pcSlice = pcPic->getSlice(0); |
---|
| 4151 | if (pcSlice->isIntra()) |
---|
| 4152 | { |
---|
| 4153 | m_gcAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits); |
---|
| 4154 | } |
---|
| 4155 | if (pcSlice->isInterP()) |
---|
| 4156 | { |
---|
| 4157 | m_gcAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits); |
---|
| 4158 | } |
---|
| 4159 | if (pcSlice->isInterB()) |
---|
| 4160 | { |
---|
| 4161 | m_gcAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits); |
---|
| 4162 | } |
---|
| 4163 | #endif |
---|
| 4164 | |
---|
| 4165 | Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B'); |
---|
| 4166 | if (!pcSlice->isReferenced()) c += 32; |
---|
| 4167 | |
---|
| 4168 | #if SVC_EXTENSION |
---|
[588] | 4169 | #if ADAPTIVE_QP_SELECTION |
---|
| 4170 | printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, nQP %d QP %d ) %10d bits", |
---|
[313] | 4171 | pcSlice->getPOC(), |
---|
| 4172 | pcSlice->getLayerId(), |
---|
| 4173 | pcSlice->getTLayer(), |
---|
| 4174 | c, |
---|
[588] | 4175 | NaluToStr( pcSlice->getNalUnitType() ).data(), |
---|
[313] | 4176 | pcSlice->getSliceQpBase(), |
---|
| 4177 | pcSlice->getSliceQp(), |
---|
| 4178 | uibits ); |
---|
| 4179 | #else |
---|
[588] | 4180 | printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, QP %d ) %10d bits", |
---|
[313] | 4181 | pcSlice->getPOC()-pcSlice->getLastIDR(), |
---|
| 4182 | pcSlice->getLayerId(), |
---|
| 4183 | pcSlice->getTLayer(), |
---|
| 4184 | c, |
---|
[713] | 4185 | NaluToStr( pcSlice->getNalUnitType() ).data(), |
---|
[313] | 4186 | pcSlice->getSliceQp(), |
---|
| 4187 | uibits ); |
---|
| 4188 | #endif |
---|
| 4189 | #else |
---|
| 4190 | #if ADAPTIVE_QP_SELECTION |
---|
| 4191 | printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits", |
---|
| 4192 | pcSlice->getPOC(), |
---|
| 4193 | pcSlice->getTLayer(), |
---|
| 4194 | c, |
---|
| 4195 | pcSlice->getSliceQpBase(), |
---|
| 4196 | pcSlice->getSliceQp(), |
---|
| 4197 | uibits ); |
---|
| 4198 | #else |
---|
| 4199 | printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits", |
---|
| 4200 | pcSlice->getPOC()-pcSlice->getLastIDR(), |
---|
| 4201 | pcSlice->getTLayer(), |
---|
| 4202 | c, |
---|
| 4203 | pcSlice->getSliceQp(), |
---|
| 4204 | uibits ); |
---|
| 4205 | #endif |
---|
| 4206 | #endif |
---|
| 4207 | |
---|
| 4208 | printf(" [Y %6.4lf dB U %6.4lf dB V %6.4lf dB]", dYPSNR, dUPSNR, dVPSNR ); |
---|
| 4209 | printf(" [ET %5.0f ]", dEncTime ); |
---|
| 4210 | |
---|
| 4211 | for (Int iRefList = 0; iRefList < 2; iRefList++) |
---|
| 4212 | { |
---|
| 4213 | printf(" [L%d ", iRefList); |
---|
| 4214 | for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++) |
---|
| 4215 | { |
---|
[442] | 4216 | #if SVC_EXTENSION |
---|
| 4217 | #if VPS_EXTN_DIRECT_REF_LAYERS |
---|
[313] | 4218 | if( pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->isILR(m_layerId) ) |
---|
| 4219 | { |
---|
[815] | 4220 | #if POC_RESET_IDC_ENCODER |
---|
[906] | 4221 | UInt refLayerId = pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId(); |
---|
| 4222 | UInt refLayerIdc = pcSlice->getReferenceLayerIdc(refLayerId); |
---|
| 4223 | assert( g_posScalingFactor[refLayerIdc][0] ); |
---|
| 4224 | assert( g_posScalingFactor[refLayerIdc][1] ); |
---|
| 4225 | |
---|
| 4226 | printf( "%d(%d, {%1.2f, %1.2f}x)", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex), refLayerId, 65536.0/g_posScalingFactor[refLayerIdc][0], 65536.0/g_posScalingFactor[refLayerIdc][1] ); |
---|
[815] | 4227 | #else |
---|
[442] | 4228 | printf( "%d(%d)", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR(), pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId() ); |
---|
[815] | 4229 | #endif |
---|
[313] | 4230 | } |
---|
| 4231 | else |
---|
[442] | 4232 | { |
---|
[815] | 4233 | #if POC_RESET_IDC_ENCODER |
---|
| 4234 | printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)); |
---|
| 4235 | #else |
---|
[442] | 4236 | printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR()); |
---|
[815] | 4237 | #endif |
---|
[442] | 4238 | } |
---|
[313] | 4239 | #endif |
---|
[442] | 4240 | if( pcSlice->getEnableTMVPFlag() && iRefList == 1 - pcSlice->getColFromL0Flag() && iRefIndex == pcSlice->getColRefIdx() ) |
---|
| 4241 | { |
---|
| 4242 | printf( "c" ); |
---|
| 4243 | } |
---|
| 4244 | |
---|
| 4245 | printf( " " ); |
---|
| 4246 | #else |
---|
[313] | 4247 | printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR()); |
---|
[442] | 4248 | #endif |
---|
[313] | 4249 | } |
---|
| 4250 | printf("]"); |
---|
| 4251 | } |
---|
[713] | 4252 | #if Q0048_CGS_3D_ASYMLUT |
---|
| 4253 | pcPic->setFrameBit( (Int)uibits ); |
---|
| 4254 | if( m_layerId && pcSlice->getPPS()->getCGSFlag() ) |
---|
| 4255 | { |
---|
[906] | 4256 | #if R0179_ENC_OPT_3DLUT_SIZE |
---|
| 4257 | m_Enc3DAsymLUTPicUpdate.update3DAsymLUTParam( &m_Enc3DAsymLUTPPS ); |
---|
| 4258 | #else |
---|
| 4259 | if( m_Enc3DAsymLUTPPS.getPPSBit() > 0 ) |
---|
| 4260 | m_Enc3DAsymLUTPicUpdate.copy3DAsymLUT( &m_Enc3DAsymLUTPPS ); |
---|
| 4261 | #endif |
---|
[713] | 4262 | m_Enc3DAsymLUTPicUpdate.updatePicCGSBits( pcSlice , m_Enc3DAsymLUTPPS.getPPSBit() ); |
---|
| 4263 | } |
---|
| 4264 | #endif |
---|
[313] | 4265 | } |
---|
| 4266 | |
---|
[442] | 4267 | |
---|
| 4268 | Void reinterlace(Pel* top, Pel* bottom, Pel* dst, UInt stride, UInt width, UInt height, Bool isTff) |
---|
| 4269 | { |
---|
| 4270 | |
---|
| 4271 | for (Int y = 0; y < height; y++) |
---|
| 4272 | { |
---|
| 4273 | for (Int x = 0; x < width; x++) |
---|
| 4274 | { |
---|
[540] | 4275 | dst[x] = isTff ? top[x] : bottom[x]; |
---|
| 4276 | dst[stride+x] = isTff ? bottom[x] : top[x]; |
---|
[442] | 4277 | } |
---|
| 4278 | top += stride; |
---|
| 4279 | bottom += stride; |
---|
| 4280 | dst += stride*2; |
---|
| 4281 | } |
---|
| 4282 | } |
---|
| 4283 | |
---|
| 4284 | Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgTop, TComPic* pcPicOrgBottom, TComPicYuv* pcPicRecTop, TComPicYuv* pcPicRecBottom, const AccessUnit& accessUnit, Double dEncTime ) |
---|
| 4285 | { |
---|
| 4286 | Int x, y; |
---|
| 4287 | |
---|
| 4288 | UInt64 uiSSDY_in = 0; |
---|
| 4289 | UInt64 uiSSDU_in = 0; |
---|
| 4290 | UInt64 uiSSDV_in = 0; |
---|
| 4291 | |
---|
| 4292 | Double dYPSNR_in = 0.0; |
---|
| 4293 | Double dUPSNR_in = 0.0; |
---|
| 4294 | Double dVPSNR_in = 0.0; |
---|
| 4295 | |
---|
| 4296 | /*------ INTERLACED PSNR -----------*/ |
---|
| 4297 | |
---|
| 4298 | /* Luma */ |
---|
| 4299 | |
---|
| 4300 | Pel* pOrgTop = pcPicOrgTop->getPicYuvOrg()->getLumaAddr(); |
---|
| 4301 | Pel* pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getLumaAddr(); |
---|
| 4302 | Pel* pRecTop = pcPicRecTop->getLumaAddr(); |
---|
| 4303 | Pel* pRecBottom = pcPicRecBottom->getLumaAddr(); |
---|
| 4304 | |
---|
| 4305 | Int iWidth; |
---|
| 4306 | Int iHeight; |
---|
| 4307 | Int iStride; |
---|
| 4308 | |
---|
| 4309 | iWidth = pcPicOrgTop->getPicYuvOrg()->getWidth () - m_pcEncTop->getPad(0); |
---|
| 4310 | iHeight = pcPicOrgTop->getPicYuvOrg()->getHeight() - m_pcEncTop->getPad(1); |
---|
| 4311 | iStride = pcPicOrgTop->getPicYuvOrg()->getStride(); |
---|
| 4312 | Int iSize = iWidth*iHeight; |
---|
| 4313 | bool isTff = pcPicOrgTop->isTopField(); |
---|
| 4314 | |
---|
| 4315 | TComPicYuv* pcOrgInterlaced = new TComPicYuv; |
---|
[494] | 4316 | #if AUXILIARY_PICTURES |
---|
| 4317 | pcOrgInterlaced->create( iWidth, iHeight << 1, pcPicOrgTop->getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth ); |
---|
| 4318 | #else |
---|
[442] | 4319 | pcOrgInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth ); |
---|
[494] | 4320 | #endif |
---|
[442] | 4321 | |
---|
| 4322 | TComPicYuv* pcRecInterlaced = new TComPicYuv; |
---|
[494] | 4323 | #if AUXILIARY_PICTURES |
---|
| 4324 | pcRecInterlaced->create( iWidth, iHeight << 1, pcPicOrgTop->getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth ); |
---|
| 4325 | #else |
---|
[442] | 4326 | pcRecInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth ); |
---|
[494] | 4327 | #endif |
---|
[442] | 4328 | |
---|
| 4329 | Pel* pOrgInterlaced = pcOrgInterlaced->getLumaAddr(); |
---|
| 4330 | Pel* pRecInterlaced = pcRecInterlaced->getLumaAddr(); |
---|
| 4331 | |
---|
| 4332 | //=== Interlace fields ==== |
---|
| 4333 | reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff); |
---|
| 4334 | reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff); |
---|
| 4335 | |
---|
| 4336 | //===== calculate PSNR ===== |
---|
| 4337 | for( y = 0; y < iHeight << 1; y++ ) |
---|
| 4338 | { |
---|
| 4339 | for( x = 0; x < iWidth; x++ ) |
---|
| 4340 | { |
---|
| 4341 | Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] ); |
---|
| 4342 | uiSSDY_in += iDiff * iDiff; |
---|
| 4343 | } |
---|
| 4344 | pOrgInterlaced += iStride; |
---|
| 4345 | pRecInterlaced += iStride; |
---|
| 4346 | } |
---|
| 4347 | |
---|
| 4348 | /*Chroma*/ |
---|
| 4349 | |
---|
| 4350 | iHeight >>= 1; |
---|
| 4351 | iWidth >>= 1; |
---|
| 4352 | iStride >>= 1; |
---|
| 4353 | |
---|
| 4354 | pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCbAddr(); |
---|
| 4355 | pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCbAddr(); |
---|
| 4356 | pRecTop = pcPicRecTop->getCbAddr(); |
---|
| 4357 | pRecBottom = pcPicRecBottom->getCbAddr(); |
---|
| 4358 | pOrgInterlaced = pcOrgInterlaced->getCbAddr(); |
---|
| 4359 | pRecInterlaced = pcRecInterlaced->getCbAddr(); |
---|
| 4360 | |
---|
| 4361 | //=== Interlace fields ==== |
---|
| 4362 | reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff); |
---|
| 4363 | reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff); |
---|
| 4364 | |
---|
| 4365 | //===== calculate PSNR ===== |
---|
| 4366 | for( y = 0; y < iHeight << 1; y++ ) |
---|
| 4367 | { |
---|
| 4368 | for( x = 0; x < iWidth; x++ ) |
---|
| 4369 | { |
---|
| 4370 | Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] ); |
---|
| 4371 | uiSSDU_in += iDiff * iDiff; |
---|
| 4372 | } |
---|
| 4373 | pOrgInterlaced += iStride; |
---|
| 4374 | pRecInterlaced += iStride; |
---|
| 4375 | } |
---|
| 4376 | |
---|
| 4377 | pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCrAddr(); |
---|
| 4378 | pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCrAddr(); |
---|
| 4379 | pRecTop = pcPicRecTop->getCrAddr(); |
---|
| 4380 | pRecBottom = pcPicRecBottom->getCrAddr(); |
---|
| 4381 | pOrgInterlaced = pcOrgInterlaced->getCrAddr(); |
---|
| 4382 | pRecInterlaced = pcRecInterlaced->getCrAddr(); |
---|
| 4383 | |
---|
| 4384 | //=== Interlace fields ==== |
---|
| 4385 | reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff); |
---|
| 4386 | reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff); |
---|
| 4387 | |
---|
| 4388 | //===== calculate PSNR ===== |
---|
| 4389 | for( y = 0; y < iHeight << 1; y++ ) |
---|
| 4390 | { |
---|
| 4391 | for( x = 0; x < iWidth; x++ ) |
---|
| 4392 | { |
---|
| 4393 | Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] ); |
---|
| 4394 | uiSSDV_in += iDiff * iDiff; |
---|
| 4395 | } |
---|
| 4396 | pOrgInterlaced += iStride; |
---|
| 4397 | pRecInterlaced += iStride; |
---|
| 4398 | } |
---|
| 4399 | |
---|
| 4400 | Int maxvalY = 255 << (g_bitDepthY-8); |
---|
| 4401 | Int maxvalC = 255 << (g_bitDepthC-8); |
---|
| 4402 | Double fRefValueY = (Double) maxvalY * maxvalY * iSize*2; |
---|
| 4403 | Double fRefValueC = (Double) maxvalC * maxvalC * iSize*2 / 4.0; |
---|
| 4404 | dYPSNR_in = ( uiSSDY_in ? 10.0 * log10( fRefValueY / (Double)uiSSDY_in ) : 99.99 ); |
---|
| 4405 | dUPSNR_in = ( uiSSDU_in ? 10.0 * log10( fRefValueC / (Double)uiSSDU_in ) : 99.99 ); |
---|
| 4406 | dVPSNR_in = ( uiSSDV_in ? 10.0 * log10( fRefValueC / (Double)uiSSDV_in ) : 99.99 ); |
---|
| 4407 | |
---|
| 4408 | /* calculate the size of the access unit, excluding: |
---|
| 4409 | * - any AnnexB contributions (start_code_prefix, zero_byte, etc.,) |
---|
| 4410 | * - SEI NAL units |
---|
| 4411 | */ |
---|
| 4412 | UInt numRBSPBytes = 0; |
---|
| 4413 | for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++) |
---|
| 4414 | { |
---|
| 4415 | UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size()); |
---|
| 4416 | |
---|
| 4417 | if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI) |
---|
| 4418 | numRBSPBytes += numRBSPBytes_nal; |
---|
| 4419 | } |
---|
| 4420 | |
---|
| 4421 | UInt uibits = numRBSPBytes * 8 ; |
---|
| 4422 | |
---|
| 4423 | //===== add PSNR ===== |
---|
| 4424 | m_gcAnalyzeAll_in.addResult (dYPSNR_in, dUPSNR_in, dVPSNR_in, (Double)uibits); |
---|
| 4425 | |
---|
| 4426 | printf("\n Interlaced frame %d: [Y %6.4lf dB U %6.4lf dB V %6.4lf dB]", pcPicOrgBottom->getPOC()/2 , dYPSNR_in, dUPSNR_in, dVPSNR_in ); |
---|
| 4427 | |
---|
| 4428 | pcOrgInterlaced->destroy(); |
---|
| 4429 | delete pcOrgInterlaced; |
---|
| 4430 | pcRecInterlaced->destroy(); |
---|
| 4431 | delete pcRecInterlaced; |
---|
| 4432 | } |
---|
| 4433 | |
---|
[540] | 4434 | |
---|
| 4435 | |
---|
[313] | 4436 | /** Function for deciding the nal_unit_type. |
---|
| 4437 | * \param pocCurr POC of the current picture |
---|
| 4438 | * \returns the nal unit type of the picture |
---|
| 4439 | * This function checks the configuration and returns the appropriate nal_unit_type for the picture. |
---|
| 4440 | */ |
---|
[595] | 4441 | NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR, Bool isField) |
---|
[313] | 4442 | { |
---|
| 4443 | if (pocCurr == 0) |
---|
| 4444 | { |
---|
| 4445 | return NAL_UNIT_CODED_SLICE_IDR_W_RADL; |
---|
| 4446 | } |
---|
[713] | 4447 | #if EFFICIENT_FIELD_IRAP |
---|
| 4448 | if(isField && pocCurr == 1) |
---|
| 4449 | { |
---|
| 4450 | // to avoid the picture becoming an IRAP |
---|
| 4451 | return NAL_UNIT_CODED_SLICE_TRAIL_R; |
---|
| 4452 | } |
---|
| 4453 | #endif |
---|
| 4454 | |
---|
| 4455 | #if ALLOW_RECOVERY_POINT_AS_RAP |
---|
| 4456 | if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0) |
---|
| 4457 | #else |
---|
[595] | 4458 | if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0) |
---|
[713] | 4459 | #endif |
---|
[313] | 4460 | { |
---|
| 4461 | if (m_pcCfg->getDecodingRefreshType() == 1) |
---|
| 4462 | { |
---|
| 4463 | return NAL_UNIT_CODED_SLICE_CRA; |
---|
| 4464 | } |
---|
| 4465 | else if (m_pcCfg->getDecodingRefreshType() == 2) |
---|
| 4466 | { |
---|
| 4467 | return NAL_UNIT_CODED_SLICE_IDR_W_RADL; |
---|
| 4468 | } |
---|
| 4469 | } |
---|
[815] | 4470 | |
---|
| 4471 | #if POC_RESET_IDC_ENCODER |
---|
| 4472 | if(m_pocCraWithoutReset > 0 && this->m_associatedIRAPType == NAL_UNIT_CODED_SLICE_CRA) |
---|
| 4473 | { |
---|
| 4474 | if(pocCurr < m_pocCraWithoutReset) |
---|
| 4475 | #else |
---|
[313] | 4476 | if(m_pocCRA>0) |
---|
| 4477 | { |
---|
| 4478 | if(pocCurr<m_pocCRA) |
---|
[815] | 4479 | #endif |
---|
[313] | 4480 | { |
---|
| 4481 | // All leading pictures are being marked as TFD pictures here since current encoder uses all |
---|
| 4482 | // reference pictures while encoding leading pictures. An encoder can ensure that a leading |
---|
| 4483 | // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by |
---|
| 4484 | // controlling the reference pictures used for encoding that leading picture. Such a leading |
---|
| 4485 | // picture need not be marked as a TFD picture. |
---|
| 4486 | return NAL_UNIT_CODED_SLICE_RASL_R; |
---|
| 4487 | } |
---|
| 4488 | } |
---|
| 4489 | if (lastIDR>0) |
---|
| 4490 | { |
---|
| 4491 | if (pocCurr < lastIDR) |
---|
| 4492 | { |
---|
| 4493 | return NAL_UNIT_CODED_SLICE_RADL_R; |
---|
| 4494 | } |
---|
| 4495 | } |
---|
| 4496 | return NAL_UNIT_CODED_SLICE_TRAIL_R; |
---|
| 4497 | } |
---|
| 4498 | |
---|
| 4499 | Double TEncGOP::xCalculateRVM() |
---|
| 4500 | { |
---|
| 4501 | Double dRVM = 0; |
---|
| 4502 | |
---|
| 4503 | if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 ) |
---|
| 4504 | { |
---|
| 4505 | // calculate RVM only for lowdelay configurations |
---|
| 4506 | std::vector<Double> vRL , vB; |
---|
| 4507 | size_t N = m_vRVM_RP.size(); |
---|
| 4508 | vRL.resize( N ); |
---|
| 4509 | vB.resize( N ); |
---|
| 4510 | |
---|
| 4511 | Int i; |
---|
| 4512 | Double dRavg = 0 , dBavg = 0; |
---|
| 4513 | vB[RVM_VCEGAM10_M] = 0; |
---|
| 4514 | for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ ) |
---|
| 4515 | { |
---|
| 4516 | vRL[i] = 0; |
---|
| 4517 | for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ ) |
---|
| 4518 | vRL[i] += m_vRVM_RP[j]; |
---|
| 4519 | vRL[i] /= ( 2 * RVM_VCEGAM10_M ); |
---|
| 4520 | vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i]; |
---|
| 4521 | dRavg += m_vRVM_RP[i]; |
---|
| 4522 | dBavg += vB[i]; |
---|
| 4523 | } |
---|
| 4524 | |
---|
| 4525 | dRavg /= ( N - 2 * RVM_VCEGAM10_M ); |
---|
| 4526 | dBavg /= ( N - 2 * RVM_VCEGAM10_M ); |
---|
| 4527 | |
---|
| 4528 | Double dSigamB = 0; |
---|
| 4529 | for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ ) |
---|
| 4530 | { |
---|
| 4531 | Double tmp = vB[i] - dBavg; |
---|
| 4532 | dSigamB += tmp * tmp; |
---|
| 4533 | } |
---|
| 4534 | dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) ); |
---|
| 4535 | |
---|
| 4536 | Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) ); |
---|
| 4537 | |
---|
| 4538 | dRVM = dSigamB / dRavg * f; |
---|
| 4539 | } |
---|
| 4540 | |
---|
| 4541 | return( dRVM ); |
---|
| 4542 | } |
---|
| 4543 | |
---|
| 4544 | /** Attaches the input bitstream to the stream in the output NAL unit |
---|
| 4545 | Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call. |
---|
| 4546 | * \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu |
---|
| 4547 | * \param rNalu target NAL unit |
---|
| 4548 | */ |
---|
| 4549 | Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream*& codedSliceData) |
---|
| 4550 | { |
---|
| 4551 | // Byte-align |
---|
| 4552 | rNalu.m_Bitstream.writeByteAlignment(); // Slice header byte-alignment |
---|
| 4553 | |
---|
| 4554 | // Perform bitstream concatenation |
---|
| 4555 | if (codedSliceData->getNumberOfWrittenBits() > 0) |
---|
| 4556 | { |
---|
| 4557 | rNalu.m_Bitstream.addSubstream(codedSliceData); |
---|
| 4558 | } |
---|
| 4559 | |
---|
| 4560 | m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream); |
---|
| 4561 | |
---|
| 4562 | codedSliceData->clear(); |
---|
| 4563 | } |
---|
| 4564 | |
---|
| 4565 | // Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt, |
---|
| 4566 | // and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value |
---|
| 4567 | Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic) |
---|
| 4568 | { |
---|
| 4569 | TComReferencePictureSet *rps = pcSlice->getRPS(); |
---|
| 4570 | if(!rps->getNumberOfLongtermPictures()) |
---|
| 4571 | { |
---|
| 4572 | return; |
---|
| 4573 | } |
---|
| 4574 | |
---|
| 4575 | // Arrange long-term reference pictures in the correct order of LSB and MSB, |
---|
| 4576 | // and assign values for pocLSBLT and MSB present flag |
---|
| 4577 | Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS]; |
---|
| 4578 | Int longtermPicsMSB[MAX_NUM_REF_PICS]; |
---|
| 4579 | Bool mSBPresentFlag[MAX_NUM_REF_PICS]; |
---|
| 4580 | ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc)); // Store POC values of LTRP |
---|
| 4581 | ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB)); // Store POC LSB values of LTRP |
---|
| 4582 | ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB)); // Store POC LSB values of LTRP |
---|
| 4583 | ::memset(indices , 0, sizeof(indices)); // Indices to aid in tracking sorted LTRPs |
---|
| 4584 | ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag)); // Indicate if MSB needs to be present |
---|
| 4585 | |
---|
| 4586 | // Get the long-term reference pictures |
---|
| 4587 | Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures(); |
---|
| 4588 | Int i, ctr = 0; |
---|
| 4589 | Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC(); |
---|
| 4590 | for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++) |
---|
| 4591 | { |
---|
| 4592 | longtermPicsPoc[ctr] = rps->getPOC(i); // LTRP POC |
---|
| 4593 | longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB |
---|
| 4594 | indices[ctr] = i; |
---|
| 4595 | longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr]; |
---|
| 4596 | } |
---|
| 4597 | Int numLongPics = rps->getNumberOfLongtermPictures(); |
---|
| 4598 | assert(ctr == numLongPics); |
---|
| 4599 | |
---|
| 4600 | // Arrange pictures in decreasing order of MSB; |
---|
| 4601 | for(i = 0; i < numLongPics; i++) |
---|
| 4602 | { |
---|
| 4603 | for(Int j = 0; j < numLongPics - 1; j++) |
---|
| 4604 | { |
---|
| 4605 | if(longtermPicsMSB[j] < longtermPicsMSB[j+1]) |
---|
| 4606 | { |
---|
| 4607 | std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]); |
---|
| 4608 | std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]); |
---|
| 4609 | std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]); |
---|
| 4610 | std::swap(indices[j] , indices[j+1] ); |
---|
| 4611 | } |
---|
| 4612 | } |
---|
| 4613 | } |
---|
| 4614 | |
---|
| 4615 | for(i = 0; i < numLongPics; i++) |
---|
| 4616 | { |
---|
| 4617 | // Check if MSB present flag should be enabled. |
---|
| 4618 | // Check if the buffer contains any pictures that have the same LSB. |
---|
| 4619 | TComList<TComPic*>::iterator iterPic = rcListPic.begin(); |
---|
| 4620 | TComPic* pcPic; |
---|
| 4621 | while ( iterPic != rcListPic.end() ) |
---|
| 4622 | { |
---|
| 4623 | pcPic = *iterPic; |
---|
| 4624 | if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i]) && // Same LSB |
---|
| 4625 | (pcPic->getSlice(0)->isReferenced()) && // Reference picture |
---|
| 4626 | (pcPic->getPOC() != longtermPicsPoc[i]) ) // Not the LTRP itself |
---|
| 4627 | { |
---|
| 4628 | mSBPresentFlag[i] = true; |
---|
| 4629 | break; |
---|
| 4630 | } |
---|
| 4631 | iterPic++; |
---|
| 4632 | } |
---|
| 4633 | } |
---|
| 4634 | |
---|
| 4635 | // tempArray for usedByCurr flag |
---|
| 4636 | Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray)); |
---|
| 4637 | for(i = 0; i < numLongPics; i++) |
---|
| 4638 | { |
---|
| 4639 | tempArray[i] = rps->getUsed(indices[i]); |
---|
| 4640 | } |
---|
| 4641 | // Now write the final values; |
---|
| 4642 | ctr = 0; |
---|
| 4643 | Int currMSB = 0, currLSB = 0; |
---|
| 4644 | // currPicPoc = currMSB + currLSB |
---|
| 4645 | currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB); |
---|
| 4646 | currMSB = pcSlice->getPOC() - currLSB; |
---|
| 4647 | |
---|
| 4648 | for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++) |
---|
| 4649 | { |
---|
| 4650 | rps->setPOC (i, longtermPicsPoc[ctr]); |
---|
| 4651 | rps->setDeltaPOC (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]); |
---|
| 4652 | rps->setUsed (i, tempArray[ctr]); |
---|
| 4653 | rps->setPocLSBLT (i, longtermPicsLSB[ctr]); |
---|
| 4654 | rps->setDeltaPocMSBCycleLT (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB); |
---|
| 4655 | rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]); |
---|
| 4656 | |
---|
| 4657 | assert(rps->getDeltaPocMSBCycleLT(i) >= 0); // Non-negative value |
---|
| 4658 | } |
---|
| 4659 | for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++) |
---|
| 4660 | { |
---|
| 4661 | for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--) |
---|
| 4662 | { |
---|
| 4663 | // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we |
---|
| 4664 | // don't have to check the MSB present flag values for this constraint. |
---|
| 4665 | assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!! |
---|
| 4666 | } |
---|
| 4667 | } |
---|
| 4668 | } |
---|
| 4669 | |
---|
| 4670 | /** Function for finding the position to insert the first of APS and non-nested BP, PT, DU info SEI messages. |
---|
| 4671 | * \param accessUnit Access Unit of the current picture |
---|
| 4672 | * This function finds the position to insert the first of APS and non-nested BP, PT, DU info SEI messages. |
---|
| 4673 | */ |
---|
| 4674 | Int TEncGOP::xGetFirstSeiLocation(AccessUnit &accessUnit) |
---|
| 4675 | { |
---|
| 4676 | // Find the location of the first SEI message |
---|
| 4677 | AccessUnit::iterator it; |
---|
| 4678 | Int seiStartPos = 0; |
---|
| 4679 | for(it = accessUnit.begin(); it != accessUnit.end(); it++, seiStartPos++) |
---|
| 4680 | { |
---|
| 4681 | if ((*it)->isSei() || (*it)->isVcl()) |
---|
| 4682 | { |
---|
| 4683 | break; |
---|
| 4684 | } |
---|
| 4685 | } |
---|
| 4686 | // assert(it != accessUnit.end()); // Triggers with some legit configurations |
---|
| 4687 | return seiStartPos; |
---|
| 4688 | } |
---|
| 4689 | |
---|
| 4690 | Void TEncGOP::dblMetric( TComPic* pcPic, UInt uiNumSlices ) |
---|
| 4691 | { |
---|
| 4692 | TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec(); |
---|
| 4693 | Pel* Rec = pcPicYuvRec->getLumaAddr( 0 ); |
---|
| 4694 | Pel* tempRec = Rec; |
---|
| 4695 | Int stride = pcPicYuvRec->getStride(); |
---|
| 4696 | UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize(); |
---|
| 4697 | UInt maxTBsize = (1<<log2maxTB); |
---|
| 4698 | const UInt minBlockArtSize = 8; |
---|
| 4699 | const UInt picWidth = pcPicYuvRec->getWidth(); |
---|
| 4700 | const UInt picHeight = pcPicYuvRec->getHeight(); |
---|
| 4701 | const UInt noCol = (picWidth>>log2maxTB); |
---|
| 4702 | const UInt noRows = (picHeight>>log2maxTB); |
---|
| 4703 | assert(noCol > 1); |
---|
| 4704 | assert(noRows > 1); |
---|
| 4705 | UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64)); |
---|
| 4706 | UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64)); |
---|
| 4707 | UInt colIdx = 0; |
---|
| 4708 | UInt rowIdx = 0; |
---|
| 4709 | Pel p0, p1, p2, q0, q1, q2; |
---|
| 4710 | |
---|
| 4711 | Int qp = pcPic->getSlice(0)->getSliceQp(); |
---|
| 4712 | Int bitdepthScale = 1 << (g_bitDepthY-8); |
---|
| 4713 | Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale; |
---|
| 4714 | const Int thr2 = (beta>>2); |
---|
| 4715 | const Int thr1 = 2*bitdepthScale; |
---|
| 4716 | UInt a = 0; |
---|
| 4717 | |
---|
| 4718 | memset(colSAD, 0, noCol*sizeof(UInt64)); |
---|
| 4719 | memset(rowSAD, 0, noRows*sizeof(UInt64)); |
---|
| 4720 | |
---|
| 4721 | if (maxTBsize > minBlockArtSize) |
---|
| 4722 | { |
---|
| 4723 | // Analyze vertical artifact edges |
---|
| 4724 | for(Int c = maxTBsize; c < picWidth; c += maxTBsize) |
---|
| 4725 | { |
---|
| 4726 | for(Int r = 0; r < picHeight; r++) |
---|
| 4727 | { |
---|
| 4728 | p2 = Rec[c-3]; |
---|
| 4729 | p1 = Rec[c-2]; |
---|
| 4730 | p0 = Rec[c-1]; |
---|
| 4731 | q0 = Rec[c]; |
---|
| 4732 | q1 = Rec[c+1]; |
---|
| 4733 | q2 = Rec[c+2]; |
---|
| 4734 | a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1); |
---|
| 4735 | if ( thr1 < a && a < thr2) |
---|
| 4736 | { |
---|
| 4737 | colSAD[colIdx] += abs(p0 - q0); |
---|
| 4738 | } |
---|
| 4739 | Rec += stride; |
---|
| 4740 | } |
---|
| 4741 | colIdx++; |
---|
| 4742 | Rec = tempRec; |
---|
| 4743 | } |
---|
| 4744 | |
---|
| 4745 | // Analyze horizontal artifact edges |
---|
| 4746 | for(Int r = maxTBsize; r < picHeight; r += maxTBsize) |
---|
| 4747 | { |
---|
| 4748 | for(Int c = 0; c < picWidth; c++) |
---|
| 4749 | { |
---|
| 4750 | p2 = Rec[c + (r-3)*stride]; |
---|
| 4751 | p1 = Rec[c + (r-2)*stride]; |
---|
| 4752 | p0 = Rec[c + (r-1)*stride]; |
---|
| 4753 | q0 = Rec[c + r*stride]; |
---|
| 4754 | q1 = Rec[c + (r+1)*stride]; |
---|
| 4755 | q2 = Rec[c + (r+2)*stride]; |
---|
| 4756 | a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1); |
---|
| 4757 | if (thr1 < a && a < thr2) |
---|
| 4758 | { |
---|
| 4759 | rowSAD[rowIdx] += abs(p0 - q0); |
---|
| 4760 | } |
---|
| 4761 | } |
---|
| 4762 | rowIdx++; |
---|
| 4763 | } |
---|
| 4764 | } |
---|
| 4765 | |
---|
| 4766 | UInt64 colSADsum = 0; |
---|
| 4767 | UInt64 rowSADsum = 0; |
---|
| 4768 | for(Int c = 0; c < noCol-1; c++) |
---|
| 4769 | { |
---|
| 4770 | colSADsum += colSAD[c]; |
---|
| 4771 | } |
---|
| 4772 | for(Int r = 0; r < noRows-1; r++) |
---|
| 4773 | { |
---|
| 4774 | rowSADsum += rowSAD[r]; |
---|
| 4775 | } |
---|
| 4776 | |
---|
| 4777 | colSADsum <<= 10; |
---|
| 4778 | rowSADsum <<= 10; |
---|
| 4779 | colSADsum /= (noCol-1); |
---|
| 4780 | colSADsum /= picHeight; |
---|
| 4781 | rowSADsum /= (noRows-1); |
---|
| 4782 | rowSADsum /= picWidth; |
---|
| 4783 | |
---|
| 4784 | UInt64 avgSAD = ((colSADsum + rowSADsum)>>1); |
---|
| 4785 | avgSAD >>= (g_bitDepthY-8); |
---|
| 4786 | |
---|
| 4787 | if ( avgSAD > 2048 ) |
---|
| 4788 | { |
---|
| 4789 | avgSAD >>= 9; |
---|
| 4790 | Int offset = Clip3(2,6,(Int)avgSAD); |
---|
| 4791 | for (Int i=0; i<uiNumSlices; i++) |
---|
| 4792 | { |
---|
| 4793 | pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true); |
---|
| 4794 | pcPic->getSlice(i)->setDeblockingFilterDisable(false); |
---|
| 4795 | pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset ); |
---|
| 4796 | pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset ); |
---|
| 4797 | } |
---|
| 4798 | } |
---|
| 4799 | else |
---|
| 4800 | { |
---|
| 4801 | for (Int i=0; i<uiNumSlices; i++) |
---|
| 4802 | { |
---|
| 4803 | pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false); |
---|
| 4804 | pcPic->getSlice(i)->setDeblockingFilterDisable( pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() ); |
---|
| 4805 | pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() ); |
---|
| 4806 | pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2() ); |
---|
| 4807 | } |
---|
| 4808 | } |
---|
| 4809 | |
---|
| 4810 | free(colSAD); |
---|
| 4811 | free(rowSAD); |
---|
| 4812 | } |
---|
[595] | 4813 | #if SVC_EXTENSION |
---|
| 4814 | #if LAYERS_NOT_PRESENT_SEI |
---|
| 4815 | SEILayersNotPresent* TEncGOP::xCreateSEILayersNotPresent () |
---|
| 4816 | { |
---|
| 4817 | UInt i = 0; |
---|
| 4818 | SEILayersNotPresent *seiLayersNotPresent = new SEILayersNotPresent(); |
---|
| 4819 | seiLayersNotPresent->m_activeVpsId = m_pcCfg->getVPS()->getVPSId(); |
---|
| 4820 | seiLayersNotPresent->m_vpsMaxLayers = m_pcCfg->getVPS()->getMaxLayers(); |
---|
| 4821 | for ( ; i < seiLayersNotPresent->m_vpsMaxLayers; i++) |
---|
| 4822 | { |
---|
| 4823 | seiLayersNotPresent->m_layerNotPresentFlag[i] = true; |
---|
| 4824 | } |
---|
| 4825 | for ( ; i < MAX_LAYERS; i++) |
---|
| 4826 | { |
---|
| 4827 | seiLayersNotPresent->m_layerNotPresentFlag[i] = false; |
---|
| 4828 | } |
---|
| 4829 | return seiLayersNotPresent; |
---|
| 4830 | } |
---|
| 4831 | #endif |
---|
| 4832 | |
---|
| 4833 | #if N0383_IL_CONSTRAINED_TILE_SETS_SEI |
---|
| 4834 | SEIInterLayerConstrainedTileSets* TEncGOP::xCreateSEIInterLayerConstrainedTileSets() |
---|
| 4835 | { |
---|
| 4836 | SEIInterLayerConstrainedTileSets *seiInterLayerConstrainedTileSets = new SEIInterLayerConstrainedTileSets(); |
---|
| 4837 | seiInterLayerConstrainedTileSets->m_ilAllTilesExactSampleValueMatchFlag = false; |
---|
| 4838 | seiInterLayerConstrainedTileSets->m_ilOneTilePerTileSetFlag = false; |
---|
| 4839 | if (!seiInterLayerConstrainedTileSets->m_ilOneTilePerTileSetFlag) |
---|
| 4840 | { |
---|
| 4841 | seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1 = m_pcCfg->getIlNumSetsInMessage() - 1; |
---|
| 4842 | if (seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1) |
---|
| 4843 | { |
---|
| 4844 | seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag = m_pcCfg->getSkippedTileSetPresentFlag(); |
---|
| 4845 | } |
---|
| 4846 | else |
---|
| 4847 | { |
---|
| 4848 | seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag = false; |
---|
| 4849 | } |
---|
| 4850 | seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1 += seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag ? 1 : 0; |
---|
| 4851 | for (UInt i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++) |
---|
| 4852 | { |
---|
| 4853 | seiInterLayerConstrainedTileSets->m_ilctsId[i] = i; |
---|
| 4854 | seiInterLayerConstrainedTileSets->m_ilNumTileRectsInSetMinus1[i] = 0; |
---|
| 4855 | for( UInt j = 0; j <= seiInterLayerConstrainedTileSets->m_ilNumTileRectsInSetMinus1[i]; j++) |
---|
| 4856 | { |
---|
| 4857 | seiInterLayerConstrainedTileSets->m_ilTopLeftTileIndex[i][j] = m_pcCfg->getTopLeftTileIndex(i); |
---|
| 4858 | seiInterLayerConstrainedTileSets->m_ilBottomRightTileIndex[i][j] = m_pcCfg->getBottomRightTileIndex(i); |
---|
| 4859 | } |
---|
| 4860 | seiInterLayerConstrainedTileSets->m_ilcIdc[i] = m_pcCfg->getIlcIdc(i); |
---|
| 4861 | if (seiInterLayerConstrainedTileSets->m_ilAllTilesExactSampleValueMatchFlag) |
---|
| 4862 | { |
---|
| 4863 | seiInterLayerConstrainedTileSets->m_ilExactSampleValueMatchFlag[i] = false; |
---|
| 4864 | } |
---|
| 4865 | } |
---|
| 4866 | } |
---|
| 4867 | |
---|
| 4868 | return seiInterLayerConstrainedTileSets; |
---|
| 4869 | } |
---|
| 4870 | |
---|
| 4871 | Void TEncGOP::xBuildTileSetsMap(TComPicSym* picSym) |
---|
| 4872 | { |
---|
| 4873 | Int numCUs = picSym->getFrameWidthInCU() * picSym->getFrameHeightInCU(); |
---|
| 4874 | |
---|
| 4875 | for (Int i = 0; i < numCUs; i++) |
---|
| 4876 | { |
---|
| 4877 | picSym->setTileSetIdxMap(i, -1, 0, false); |
---|
| 4878 | } |
---|
| 4879 | |
---|
| 4880 | for (Int i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++) |
---|
| 4881 | { |
---|
| 4882 | TComTile* topLeftTile = picSym->getTComTile(m_pcCfg->getTopLeftTileIndex(i)); |
---|
| 4883 | TComTile* bottomRightTile = picSym->getTComTile(m_pcCfg->getBottomRightTileIndex(i)); |
---|
| 4884 | Int tileSetLeftEdgePosInCU = topLeftTile->getRightEdgePosInCU() - topLeftTile->getTileWidth() + 1; |
---|
| 4885 | Int tileSetRightEdgePosInCU = bottomRightTile->getRightEdgePosInCU(); |
---|
| 4886 | Int tileSetTopEdgePosInCU = topLeftTile->getBottomEdgePosInCU() - topLeftTile->getTileHeight() + 1; |
---|
| 4887 | Int tileSetBottomEdgePosInCU = bottomRightTile->getBottomEdgePosInCU(); |
---|
| 4888 | assert(tileSetLeftEdgePosInCU < tileSetRightEdgePosInCU && tileSetTopEdgePosInCU < tileSetBottomEdgePosInCU); |
---|
| 4889 | for (Int j = tileSetTopEdgePosInCU; j <= tileSetBottomEdgePosInCU; j++) |
---|
| 4890 | { |
---|
| 4891 | for (Int k = tileSetLeftEdgePosInCU; k <= tileSetRightEdgePosInCU; k++) |
---|
| 4892 | { |
---|
| 4893 | picSym->setTileSetIdxMap(j * picSym->getFrameWidthInCU() + k, i, m_pcCfg->getIlcIdc(i), false); |
---|
| 4894 | } |
---|
| 4895 | } |
---|
| 4896 | } |
---|
| 4897 | |
---|
| 4898 | if (m_pcCfg->getSkippedTileSetPresentFlag()) |
---|
| 4899 | { |
---|
| 4900 | Int skippedTileSetIdx = m_pcCfg->getIlNumSetsInMessage(); |
---|
| 4901 | for (Int i = 0; i < numCUs; i++) |
---|
| 4902 | { |
---|
| 4903 | if (picSym->getTileSetIdxMap(i) < 0) |
---|
| 4904 | { |
---|
| 4905 | picSym->setTileSetIdxMap(i, skippedTileSetIdx, 0, true); |
---|
| 4906 | } |
---|
| 4907 | } |
---|
| 4908 | } |
---|
| 4909 | } |
---|
| 4910 | #endif |
---|
[644] | 4911 | |
---|
| 4912 | #if O0164_MULTI_LAYER_HRD |
---|
[906] | 4913 | #if VPS_VUI_BSP_HRD_PARAMS |
---|
| 4914 | SEIScalableNesting* TEncGOP::xCreateBspNestingSEI(TComSlice *pcSlice, Int olsIdx, Int partitioningSchemeIdx, Int bspIdx) |
---|
| 4915 | #else |
---|
[644] | 4916 | SEIScalableNesting* TEncGOP::xCreateBspNestingSEI(TComSlice *pcSlice) |
---|
[906] | 4917 | #endif |
---|
[644] | 4918 | { |
---|
| 4919 | SEIScalableNesting *seiScalableNesting = new SEIScalableNesting(); |
---|
| 4920 | SEIBspInitialArrivalTime *seiBspInitialArrivalTime = new SEIBspInitialArrivalTime(); |
---|
| 4921 | SEIBspNesting *seiBspNesting = new SEIBspNesting(); |
---|
| 4922 | SEIBufferingPeriod *seiBufferingPeriod = new SEIBufferingPeriod(); |
---|
| 4923 | |
---|
| 4924 | // Scalable nesting SEI |
---|
| 4925 | |
---|
| 4926 | seiScalableNesting->m_bitStreamSubsetFlag = 1; // If the nested SEI messages are picture buffereing SEI mesages, picure timing SEI messages or sub-picture timing SEI messages, bitstream_subset_flag shall be equal to 1 |
---|
| 4927 | seiScalableNesting->m_nestingOpFlag = 1; |
---|
| 4928 | seiScalableNesting->m_defaultOpFlag = 0; |
---|
| 4929 | seiScalableNesting->m_nestingNumOpsMinus1 = 0; //nesting_num_ops_minus1 |
---|
[906] | 4930 | #if VPS_VUI_BSP_HRD_PARAMS |
---|
| 4931 | seiScalableNesting->m_nestingOpIdx[0] = pcSlice->getVPS()->getOutputLayerSetIdx(olsIdx); |
---|
| 4932 | seiScalableNesting->m_nestingMaxTemporalIdPlus1[0] = 6 + 1; |
---|
| 4933 | #else |
---|
[644] | 4934 | seiScalableNesting->m_nestingOpIdx[0] = 1; |
---|
[906] | 4935 | #endif |
---|
[644] | 4936 | seiScalableNesting->m_allLayersFlag = 0; |
---|
| 4937 | seiScalableNesting->m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1; //nesting_no_op_max_temporal_id_plus1 |
---|
| 4938 | seiScalableNesting->m_nestingNumLayersMinus1 = 1 - 1; //nesting_num_layers_minus1 |
---|
| 4939 | seiScalableNesting->m_nestingLayerId[0] = 0; |
---|
| 4940 | seiScalableNesting->m_callerOwnsSEIs = true; |
---|
| 4941 | |
---|
| 4942 | // Bitstream partition nesting SEI |
---|
| 4943 | |
---|
| 4944 | seiBspNesting->m_bspIdx = 0; |
---|
| 4945 | seiBspNesting->m_callerOwnsSEIs = true; |
---|
| 4946 | |
---|
| 4947 | // Buffering period SEI |
---|
| 4948 | |
---|
| 4949 | UInt uiInitialCpbRemovalDelay = (90000/2); // 0.5 sec |
---|
| 4950 | seiBufferingPeriod->m_initialCpbRemovalDelay [0][0] = uiInitialCpbRemovalDelay; |
---|
| 4951 | seiBufferingPeriod->m_initialCpbRemovalDelayOffset[0][0] = uiInitialCpbRemovalDelay; |
---|
| 4952 | seiBufferingPeriod->m_initialCpbRemovalDelay [0][1] = uiInitialCpbRemovalDelay; |
---|
| 4953 | seiBufferingPeriod->m_initialCpbRemovalDelayOffset[0][1] = uiInitialCpbRemovalDelay; |
---|
| 4954 | |
---|
| 4955 | Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale(); |
---|
| 4956 | |
---|
| 4957 | UInt uiTmp = (UInt)( dTmp * 90000.0 ); |
---|
| 4958 | uiInitialCpbRemovalDelay -= uiTmp; |
---|
| 4959 | uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 ); |
---|
| 4960 | seiBufferingPeriod->m_initialAltCpbRemovalDelay [0][0] = uiInitialCpbRemovalDelay; |
---|
| 4961 | seiBufferingPeriod->m_initialAltCpbRemovalDelayOffset[0][0] = uiInitialCpbRemovalDelay; |
---|
| 4962 | seiBufferingPeriod->m_initialAltCpbRemovalDelay [0][1] = uiInitialCpbRemovalDelay; |
---|
| 4963 | seiBufferingPeriod->m_initialAltCpbRemovalDelayOffset[0][1] = uiInitialCpbRemovalDelay; |
---|
| 4964 | |
---|
| 4965 | seiBufferingPeriod->m_rapCpbParamsPresentFlag = 0; |
---|
| 4966 | //for the concatenation, it can be set to one during splicing. |
---|
| 4967 | seiBufferingPeriod->m_concatenationFlag = 0; |
---|
| 4968 | //since the temporal layer HRD is not ready, we assumed it is fixed |
---|
| 4969 | seiBufferingPeriod->m_auCpbRemovalDelayDelta = 1; |
---|
| 4970 | seiBufferingPeriod->m_cpbDelayOffset = 0; |
---|
| 4971 | seiBufferingPeriod->m_dpbDelayOffset = 0; |
---|
| 4972 | |
---|
| 4973 | // Intial arrival time SEI message |
---|
| 4974 | |
---|
| 4975 | seiBspInitialArrivalTime->m_nalInitialArrivalDelay[0] = 0; |
---|
| 4976 | seiBspInitialArrivalTime->m_vclInitialArrivalDelay[0] = 0; |
---|
| 4977 | |
---|
| 4978 | |
---|
| 4979 | seiBspNesting->m_nestedSEIs.push_back(seiBufferingPeriod); |
---|
| 4980 | seiBspNesting->m_nestedSEIs.push_back(seiBspInitialArrivalTime); |
---|
[906] | 4981 | #if VPS_VUI_BSP_HRD_PARAMS |
---|
| 4982 | seiBspNesting->m_bspIdx = bspIdx; |
---|
| 4983 | seiBspNesting->m_seiOlsIdx = olsIdx; |
---|
| 4984 | seiBspNesting->m_seiPartitioningSchemeIdx = partitioningSchemeIdx; |
---|
| 4985 | #endif |
---|
[644] | 4986 | seiScalableNesting->m_nestedSEIs.push_back(seiBspNesting); // BSP nesting SEI is contained in scalable nesting SEI |
---|
| 4987 | |
---|
| 4988 | return seiScalableNesting; |
---|
| 4989 | } |
---|
| 4990 | #endif |
---|
| 4991 | |
---|
[713] | 4992 | #if Q0048_CGS_3D_ASYMLUT |
---|
| 4993 | Void TEncGOP::xDetermin3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS ) |
---|
| 4994 | { |
---|
| 4995 | Int nCGSFlag = pSlice->getPPS()->getCGSFlag(); |
---|
| 4996 | m_Enc3DAsymLUTPPS.setPPSBit( 0 ); |
---|
| 4997 | Double dErrorUpdatedPPS = 0 , dErrorPPS = 0; |
---|
[906] | 4998 | |
---|
| 4999 | #if R0179_ENC_OPT_3DLUT_SIZE |
---|
| 5000 | Int nTLthres = m_pcCfg->getCGSLutSizeRDO() ? 2:7; |
---|
| 5001 | Double dFrameLambda; |
---|
| 5002 | #if FULL_NBIT |
---|
| 5003 | Int SHIFT_QP = 12 + 6 * (pSlice->getBitDepthY() - 8); |
---|
| 5004 | #else |
---|
| 5005 | Int SHIFT_QP = 12; |
---|
| 5006 | #endif |
---|
| 5007 | Int QP = pSlice->getSliceQp(); |
---|
| 5008 | |
---|
| 5009 | // set frame lambda |
---|
| 5010 | dFrameLambda = 0.68 * pow (2, (QP - SHIFT_QP) / 3.0) * (m_pcCfg->getGOPSize() > 1 && pSlice->isInterB()? 2 : 1); |
---|
| 5011 | |
---|
| 5012 | if(m_pcCfg->getCGSLutSizeRDO() == 1 && (!bSignalPPS && (pSlice->getDepth() < nTLthres))) |
---|
| 5013 | dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB(), dFrameLambda ); |
---|
| 5014 | else if (pSlice->getDepth() >= nTLthres) |
---|
| 5015 | dErrorUpdatedPPS = MAX_DOUBLE; |
---|
| 5016 | else // if (m_pcCfg->getCGSLutSizeRDO() = 0 || bSignalPPS) |
---|
| 5017 | #endif |
---|
| 5018 | dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB() ); |
---|
| 5019 | |
---|
| 5020 | |
---|
[713] | 5021 | if( bSignalPPS ) |
---|
| 5022 | { |
---|
| 5023 | m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate ); |
---|
| 5024 | pSlice->setCGSOverWritePPS( 1 ); // regular PPS update |
---|
| 5025 | } |
---|
| 5026 | else if( nCGSFlag ) |
---|
| 5027 | { |
---|
[906] | 5028 | #if R0179_ENC_OPT_3DLUT_SIZE |
---|
| 5029 | if(pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R || pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N) |
---|
| 5030 | { |
---|
| 5031 | pSlice->setCGSOverWritePPS( 0 ); |
---|
| 5032 | } |
---|
| 5033 | else if (pSlice->getDepth() >= nTLthres) |
---|
| 5034 | { |
---|
| 5035 | pSlice->setCGSOverWritePPS( 0 ); |
---|
| 5036 | } |
---|
| 5037 | else |
---|
| 5038 | { |
---|
| 5039 | #endif |
---|
| 5040 | dErrorPPS = m_Enc3DAsymLUTPPS.estimateDistWithCur3DAsymLUT( pCurPic , refLayerIdc ); |
---|
| 5041 | Double dFactor = pCfg->getIntraPeriod() == 1 ? 0.99 : 0.9; |
---|
| 5042 | |
---|
| 5043 | #if R0179_ENC_OPT_3DLUT_SIZE |
---|
| 5044 | if( m_pcCfg->getCGSLutSizeRDO() ) |
---|
| 5045 | { |
---|
| 5046 | dErrorPPS = dErrorPPS/m_Enc3DAsymLUTPicUpdate.getDistFactor(pSlice->getSliceType(), pSlice->getDepth()); |
---|
| 5047 | } |
---|
| 5048 | #endif |
---|
| 5049 | pSlice->setCGSOverWritePPS( dErrorUpdatedPPS < dFactor * dErrorPPS ); |
---|
| 5050 | #if R0179_ENC_OPT_3DLUT_SIZE |
---|
| 5051 | } |
---|
| 5052 | #endif |
---|
[713] | 5053 | if( pSlice->getCGSOverWritePPS() ) |
---|
| 5054 | { |
---|
| 5055 | m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate ); |
---|
| 5056 | } |
---|
| 5057 | } |
---|
| 5058 | pSlice->getPPS()->setCGSOutputBitDepthY( m_Enc3DAsymLUTPPS.getOutputBitDepthY() ); |
---|
| 5059 | pSlice->getPPS()->setCGSOutputBitDepthC( m_Enc3DAsymLUTPPS.getOutputBitDepthC() ); |
---|
| 5060 | } |
---|
| 5061 | |
---|
| 5062 | Void TEncGOP::downScalePic( TComPicYuv* pcYuvSrc, TComPicYuv* pcYuvDest) |
---|
| 5063 | { |
---|
| 5064 | Int inputBitDepth = g_bitDepthYLayer[m_layerId]; |
---|
| 5065 | Int outputBitDepth = g_bitDepthYLayer[m_layerId]; |
---|
| 5066 | { |
---|
| 5067 | pcYuvSrc->setBorderExtension(false); |
---|
| 5068 | pcYuvSrc->extendPicBorder (); // extend the border. |
---|
| 5069 | pcYuvSrc->setBorderExtension(false); |
---|
| 5070 | |
---|
| 5071 | Int iWidth = pcYuvSrc->getWidth(); |
---|
| 5072 | Int iHeight =pcYuvSrc->getHeight(); |
---|
| 5073 | |
---|
| 5074 | if(!m_temp) |
---|
[815] | 5075 | { |
---|
[713] | 5076 | initDs(iWidth, iHeight, m_pcCfg->getIntraPeriod()>1); |
---|
[815] | 5077 | } |
---|
[713] | 5078 | |
---|
| 5079 | filterImg(pcYuvSrc->getLumaAddr(), pcYuvSrc->getStride(), pcYuvDest->getLumaAddr(), pcYuvDest->getStride(), iHeight, iWidth, inputBitDepth-outputBitDepth, 0); |
---|
| 5080 | filterImg(pcYuvSrc->getCbAddr(), pcYuvSrc->getCStride(), pcYuvDest->getCbAddr(), pcYuvDest->getCStride(), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 1); |
---|
| 5081 | filterImg(pcYuvSrc->getCrAddr(), pcYuvSrc->getCStride(), pcYuvDest->getCrAddr(), pcYuvDest->getCStride(), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 2); |
---|
| 5082 | } |
---|
| 5083 | } |
---|
[815] | 5084 | const Int TEncGOP::m_phase_filter_0_t0[4][13]={ |
---|
[713] | 5085 | {0, 2, -3, -9, 6, 39, 58, 39, 6, -9, -3, 2, 0}, |
---|
| 5086 | {0, 0, 0, -2, 8,-20, 116, 34, -10, 2, 0, 0, 0}, //{0, 1, -1, -8, -1, 31, 57, 47, 13, -7, -5, 1, 0}, // |
---|
| 5087 | {0, 1, 0, -7, -5, 22, 53, 53, 22, -5, -7, 0, 1}, |
---|
| 5088 | {0, 0, 1, -5, -7, 13, 47, 57, 31, -1, -8,-1, 1} |
---|
| 5089 | }; |
---|
| 5090 | |
---|
[815] | 5091 | const Int TEncGOP::m_phase_filter_0_t1[4][13]={ |
---|
[713] | 5092 | {0, 4, 0, -12, 0, 40, 64, 40, 0, -12, 0, 4, 0}, |
---|
| 5093 | {0, 0, 0, -2, 8,-20, 116,34,-10, 2, 0, 0, 0}, //{0, 1, -1, -8, -1, 31, 57, 47, 13, -7, -5, 1, 0}, // |
---|
| 5094 | {0, 1, 0, -7, -5, 22, 53, 53, 22, -5, -7, 0, 1}, |
---|
| 5095 | {0, 0, 1, -5, -7, 13, 47, 57, 31, -1, -8,-1, 1} |
---|
| 5096 | }; |
---|
[815] | 5097 | const Int TEncGOP::m_phase_filter_0_t1_chroma[4][13]={ |
---|
[713] | 5098 | {0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0}, |
---|
| 5099 | {0, 0, 0, -2, 8,-20, 116,34,-10, 2, 0, 0, 0}, //{0, 1, -1, -8, -1, 31, 57, 47, 13, -7, -5, 1, 0}, // |
---|
| 5100 | {0, 1, 0, -7, -5, 22, 53, 53, 22, -5, -7, 0, 1}, |
---|
| 5101 | {0, 0, 1, -5, -7, 13, 47, 57, 31, -1, -8,-1, 1} |
---|
| 5102 | }; |
---|
| 5103 | |
---|
[815] | 5104 | const Int TEncGOP::m_phase_filter_1[8][13]={ |
---|
[713] | 5105 | {0, 0, 5, -6, -10,37, 76, 37,-10, -6, 5, 0, 0}, |
---|
| 5106 | {0, -1, 5, -3, -12,29, 75, 45, -7, -8, 5, 0, 0}, |
---|
| 5107 | {0, -1, 4, -1, -13,22, 73, 52, -3, -10, 4, 1, 0}, |
---|
| 5108 | {0, -1, 4, 1, -13,14, 70, 59, 2, -12, 3, 2, -1}, |
---|
| 5109 | {0, -1, 3, 2, -13, 8, 65, 65, 8, -13, 2, 3, -1}, |
---|
| 5110 | {0, -1, 2, 3, -12, 2, 59, 70, 14, -13, 1, 4, -1}, |
---|
| 5111 | {0, 0, 1, 4, -10,-3, 52, 73, 22, -13,-1, 4, -1}, |
---|
| 5112 | {0, 0, 0, 5, -8,-7, 45, 75, 29, -12,-3, 5, -1} |
---|
| 5113 | }; |
---|
| 5114 | |
---|
[815] | 5115 | #if CGS_GCC_NO_VECTORIZATION |
---|
| 5116 | #ifdef __GNUC__ |
---|
| 5117 | #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) |
---|
| 5118 | #if GCC_VERSION > 40600 |
---|
| 5119 | __attribute__((optimize("no-tree-vectorize"))) |
---|
| 5120 | #endif |
---|
| 5121 | #endif |
---|
| 5122 | #endif |
---|
[713] | 5123 | Void TEncGOP::filterImg( |
---|
| 5124 | Pel *src, |
---|
| 5125 | Int iSrcStride, |
---|
| 5126 | Pel *dst, |
---|
| 5127 | Int iDstStride, |
---|
| 5128 | Int height1, |
---|
| 5129 | Int width1, |
---|
| 5130 | Int shift, |
---|
| 5131 | Int plane) |
---|
| 5132 | { |
---|
| 5133 | Int length = m_iTap; |
---|
| 5134 | Int height2,width2; |
---|
| 5135 | Int k,iSum; |
---|
| 5136 | Int i0, div_i0, i1; |
---|
| 5137 | Int j0, div_j0, j1; |
---|
| 5138 | const Int *p_filter; |
---|
| 5139 | Pel *p_src, *p_dst; |
---|
| 5140 | Pel *p_src_line, *p_dst_line; |
---|
| 5141 | Int **p_temp, *p_tmp; |
---|
| 5142 | Int shift2 = 2*7+shift; |
---|
| 5143 | Int shift_round = (1 << (shift2 - 1)); |
---|
| 5144 | Int iMax = (1<<(g_bitDepthY-shift))-1; |
---|
| 5145 | height2 = (height1 * m_iM) / m_iN; |
---|
| 5146 | width2 = (width1 * m_iM) / m_iN; |
---|
| 5147 | |
---|
| 5148 | m_phase_filter = plane? m_phase_filter_chroma : m_phase_filter_luma; |
---|
| 5149 | |
---|
| 5150 | // horizontal filtering |
---|
| 5151 | p_src_line = src; |
---|
| 5152 | for(j1 = 0; j1 < height1; j1++) |
---|
| 5153 | { |
---|
| 5154 | i0=-m_iN; |
---|
| 5155 | p_tmp = m_temp[j1]; |
---|
| 5156 | |
---|
| 5157 | for(i1 = 0; i1 < width2; i1++) |
---|
| 5158 | { |
---|
| 5159 | i0 += m_iN; |
---|
| 5160 | div_i0 = (i0 / m_iM); |
---|
| 5161 | p_src = p_src_line + ( div_i0 - (length >> 1)); |
---|
| 5162 | p_filter = m_phase_filter[i0 - div_i0 * m_iM]; // phase_filter[i0 % M] |
---|
| 5163 | iSum = 0; |
---|
| 5164 | for(k = 0; k < length; k++) |
---|
| 5165 | { |
---|
| 5166 | iSum += (*p_src++) * (*p_filter++); |
---|
| 5167 | } |
---|
| 5168 | *p_tmp++ = iSum; |
---|
| 5169 | } |
---|
| 5170 | p_src_line += iSrcStride; |
---|
| 5171 | } |
---|
| 5172 | |
---|
| 5173 | // pad temp (vertical) |
---|
| 5174 | for (k=-(length>>1); k<0; k++) |
---|
[815] | 5175 | { |
---|
| 5176 | memcpy(m_temp[k], m_temp[0], width2*sizeof(Int)); |
---|
| 5177 | } |
---|
[713] | 5178 | for (k=height1; k<(height1+(length>>1)); k++) |
---|
[815] | 5179 | { |
---|
| 5180 | memcpy(m_temp[k], m_temp[k-1], (width2)* sizeof(Int)); |
---|
| 5181 | } |
---|
[713] | 5182 | |
---|
| 5183 | // vertical filtering |
---|
| 5184 | j0 = (plane == 0) ? -m_iN : -(m_iN-1); |
---|
| 5185 | |
---|
| 5186 | p_dst_line = dst; |
---|
| 5187 | for(j1 = 0; j1 < height2; j1++) |
---|
| 5188 | { |
---|
| 5189 | j0 += m_iN; |
---|
| 5190 | div_j0 = (j0 / m_iM); |
---|
| 5191 | p_dst = p_dst_line; |
---|
| 5192 | p_temp = &m_temp[div_j0 - (length>>1)]; |
---|
| 5193 | p_filter = m_phase_filter[j0 - div_j0 * m_iM]; // phase_filter[j0 % M] |
---|
| 5194 | for(i1 = 0; i1 < width2;i1++) |
---|
| 5195 | { |
---|
| 5196 | iSum=0; |
---|
| 5197 | for(k = 0; k < length; k++) |
---|
| 5198 | { |
---|
| 5199 | iSum += p_temp[k][i1] * p_filter[k]; |
---|
| 5200 | } |
---|
| 5201 | iSum=((iSum + shift_round) >> shift2); |
---|
[815] | 5202 | *p_dst++ = (Short)(iSum > iMax ? iMax : (iSum < 0 ? 0 : iSum)); |
---|
[713] | 5203 | } |
---|
| 5204 | p_dst_line += iDstStride; |
---|
| 5205 | } |
---|
| 5206 | } |
---|
| 5207 | |
---|
| 5208 | Void TEncGOP::initDs(Int iWidth, Int iHeight, Int iType) |
---|
| 5209 | { |
---|
| 5210 | m_iTap = 13; |
---|
| 5211 | if(g_posScalingFactor[0][0] == (1<<15)) |
---|
| 5212 | { |
---|
| 5213 | m_iM = 4; |
---|
| 5214 | m_iN = 8; |
---|
| 5215 | m_phase_filter_luma = iType? m_phase_filter_0_t1 : m_phase_filter_0_t0; |
---|
| 5216 | m_phase_filter_chroma = m_phase_filter_0_t1_chroma; |
---|
| 5217 | } |
---|
| 5218 | else |
---|
| 5219 | { |
---|
| 5220 | m_iM = 8; |
---|
| 5221 | m_iN = 12; |
---|
| 5222 | m_phase_filter_luma = m_phase_filter_chroma = m_phase_filter_1; |
---|
| 5223 | m_phase_filter = m_phase_filter_1; |
---|
| 5224 | } |
---|
| 5225 | |
---|
| 5226 | get_mem2DintWithPad (&m_temp, iHeight, iWidth*m_iM/m_iN, m_iTap>>1, 0); |
---|
| 5227 | } |
---|
| 5228 | |
---|
| 5229 | Int TEncGOP::get_mem2DintWithPad(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX) |
---|
| 5230 | { |
---|
| 5231 | Int i; |
---|
| 5232 | Int *curr = NULL; |
---|
| 5233 | Int iHeight, iWidth; |
---|
| 5234 | |
---|
| 5235 | iHeight = dim0+2*iPadY; |
---|
| 5236 | iWidth = dim1+2*iPadX; |
---|
| 5237 | (*array2D) = (Int**)malloc(iHeight*sizeof(Int*)); |
---|
| 5238 | *(*array2D) = (Int* )xMalloc(Int, iHeight*iWidth); |
---|
| 5239 | |
---|
| 5240 | (*array2D)[0] += iPadX; |
---|
| 5241 | curr = (*array2D)[0]; |
---|
| 5242 | for(i = 1 ; i < iHeight; i++) |
---|
| 5243 | { |
---|
| 5244 | curr += iWidth; |
---|
| 5245 | (*array2D)[i] = curr; |
---|
| 5246 | } |
---|
| 5247 | (*array2D) = &((*array2D)[iPadY]); |
---|
| 5248 | |
---|
| 5249 | return 0; |
---|
| 5250 | } |
---|
| 5251 | |
---|
| 5252 | Void TEncGOP::free_mem2DintWithPad(Int **array2D, Int iPadY, Int iPadX) |
---|
| 5253 | { |
---|
| 5254 | if (array2D) |
---|
| 5255 | { |
---|
| 5256 | if (*array2D) |
---|
[815] | 5257 | { |
---|
[713] | 5258 | xFree(array2D[-iPadY]-iPadX); |
---|
[815] | 5259 | } |
---|
[713] | 5260 | else |
---|
[815] | 5261 | { |
---|
[713] | 5262 | printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n"); |
---|
[815] | 5263 | } |
---|
[713] | 5264 | |
---|
| 5265 | free (&array2D[-iPadY]); |
---|
| 5266 | } |
---|
| 5267 | else |
---|
| 5268 | { |
---|
| 5269 | printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n"); |
---|
| 5270 | } |
---|
| 5271 | } |
---|
| 5272 | #endif |
---|
[595] | 5273 | #endif //SVC_EXTENSION |
---|
| 5274 | |
---|
[313] | 5275 | //! \} |
---|