Ticket #266: EncSlice.cpp

File EncSlice.cpp, 82.1 KB (added by seuhong, 5 years ago)
Line 
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 *
6 * Copyright (c) 2010-2019, ITU/ISO/IEC
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     EncSlice.cpp
35    \brief    slice encoder class
36*/
37
38#include "EncSlice.h"
39
40#include "EncLib.h"
41#include "CommonLib/UnitTools.h"
42#include "CommonLib/Picture.h"
43#if K0149_BLOCK_STATISTICS
44#include "CommonLib/dtrace_blockstatistics.h"
45#endif
46
47#if ENABLE_WPP_PARALLELISM
48#include <mutex>
49extern recursive_mutex g_cache_mutex;
50#endif
51
52#include <math.h>
53
54//! \ingroup EncoderLib
55//! \{
56
57// ====================================================================================================================
58// Constructor / destructor / create / destroy
59// ====================================================================================================================
60
61EncSlice::EncSlice()
62 : m_encCABACTableIdx(I_SLICE)
63#if ENABLE_QPA
64 , m_adaptedLumaQP(-1)
65#endif
66{
67}
68
69EncSlice::~EncSlice()
70{
71  destroy();
72}
73
74void EncSlice::create( int iWidth, int iHeight, ChromaFormat chromaFormat, uint32_t iMaxCUWidth, uint32_t iMaxCUHeight, uint8_t uhTotalDepth )
75{
76}
77
78void EncSlice::destroy()
79{
80  // free lambda and QP arrays
81  m_vdRdPicLambda.clear();
82  m_vdRdPicQp.clear();
83  m_viRdPicQp.clear();
84}
85
86void EncSlice::init( EncLib* pcEncLib, const SPS& sps )
87{
88  m_pcCfg             = pcEncLib;
89  m_pcLib             = pcEncLib;
90  m_pcListPic         = pcEncLib->getListPic();
91
92  m_pcGOPEncoder      = pcEncLib->getGOPEncoder();
93  m_pcCuEncoder       = pcEncLib->getCuEncoder();
94  m_pcInterSearch     = pcEncLib->getInterSearch();
95  m_CABACWriter       = pcEncLib->getCABACEncoder()->getCABACWriter   (&sps);
96  m_CABACEstimator    = pcEncLib->getCABACEncoder()->getCABACEstimator(&sps);
97  m_pcTrQuant         = pcEncLib->getTrQuant();
98  m_pcRdCost          = pcEncLib->getRdCost();
99
100  // create lambda and QP arrays
101  m_vdRdPicLambda.resize(m_pcCfg->getDeltaQpRD() * 2 + 1 );
102  m_vdRdPicQp.resize(    m_pcCfg->getDeltaQpRD() * 2 + 1 );
103  m_viRdPicQp.resize(    m_pcCfg->getDeltaQpRD() * 2 + 1 );
104  m_pcRateCtrl        = pcEncLib->getRateCtrl();
105}
106
107void
108EncSlice::setUpLambda( Slice* slice, const double dLambda, int iQP)
109{
110  // store lambda
111  m_pcRdCost ->setLambda( dLambda, slice->getSPS()->getBitDepths() );
112
113  // for RDO
114  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
115  double dLambdas[MAX_NUM_COMPONENT] = { dLambda };
116  for( uint32_t compIdx = 1; compIdx < MAX_NUM_COMPONENT; compIdx++ )
117  {
118    const ComponentID compID = ComponentID( compIdx );
119    int chromaQPOffset       = slice->getPPS()->getQpOffset( compID ) + slice->getSliceChromaQpDelta( compID );
120    int qpc                  = ( iQP + chromaQPOffset < 0 ) ? iQP : getScaledChromaQP( iQP + chromaQPOffset, m_pcCfg->getChromaFormatIdc() );
121    double tmpWeight         = pow( 2.0, ( iQP - qpc ) / 3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
122#if JVET_N0193_LFNST
123    if( m_pcCfg->getDepQuantEnabledFlag() && !( m_pcCfg->getLFNST() ) )
124#else
125    if( m_pcCfg->getDepQuantEnabledFlag() )
126#endif
127    {
128      tmpWeight *= ( m_pcCfg->getGOPSize() >= 8 ? pow( 2.0, 0.1/3.0 ) : pow( 2.0, 0.2/3.0 ) );  // increase chroma weight for dependent quantization (in order to reduce bit rate shift from chroma to luma)
129    }
130    m_pcRdCost->setDistortionWeight( compID, tmpWeight );
131#if ENABLE_WPP_PARALLELISM
132    for( int jId = 1; jId < ( m_pcLib->getNumWppThreads() + m_pcLib->getNumWppExtraLines() ); jId++ )
133    {
134      m_pcLib->getRdCost( slice->getPic()->scheduler.getWppDataId( jId ) )->setDistortionWeight( compID, tmpWeight );
135    }
136#endif
137    dLambdas[compIdx] = dLambda / tmpWeight;
138  }
139
140#if RDOQ_CHROMA_LAMBDA
141  // for RDOQ
142  m_pcTrQuant->setLambdas( dLambdas );
143#else
144  m_pcTrQuant->setLambda( dLambda );
145#endif
146
147  // for SAO
148  slice->setLambdas( dLambdas );
149}
150
151#if ENABLE_QPA
152
153static inline int apprI3Log2 (const double d) // rounded 3*log2(d)
154{
155  return d < 1.5e-13 ? -128 : int (floor (3.0 * log (d) / log (2.0) + 0.5));
156}
157
158static inline int lumaDQPOffset (const uint32_t avgLumaValue, const int bitDepth)
159{
160  return (1 - int ((3 * uint64_t (avgLumaValue * avgLumaValue)) >> uint64_t (2 * bitDepth - 1)));
161}
162
163static void filterAndCalculateAverageEnergies (const Pel* pSrc, const int  iSrcStride,
164                                               double &hpEner,  const int  iHeight,    const int iWidth,
165                                               const uint32_t uBitDepth /* luma bit-depth (4-16) */)
166{
167  uint64_t saAct = 0;
168
169  // skip first row as there may be a black border frame
170  pSrc += iSrcStride;
171  // center rows
172  for (int y = 1; y < iHeight - 1; y++)
173  {
174    // skip column as there may be a black border frame
175
176    for (int x = 1; x < iWidth - 1; x++) // and columns
177    {
178      const int f = 12 * (int)pSrc[] - 2 * ((int)pSrc[x-1] + (int)pSrc[x+1] + (int)pSrc[-iSrcStride] + (int)pSrc[+iSrcStride])
179                       - (int)pSrc[x-1-iSrcStride] - (int)pSrc[x+1-iSrcStride] - (int)pSrc[x-1+iSrcStride] - (int)pSrc[x+1+iSrcStride];
180      saAct += abs (f);
181    }
182    // skip column as there may be a black border frame
183    pSrc += iSrcStride;
184  }
185  // skip last row as there may be a black border frame
186
187  hpEner = double(saAct) / double((iWidth - 2) * (iHeight - 2));
188
189  // lower limit, compensate for highpass amplification
190  if (hpEner < double(1 << (uBitDepth - 4))) hpEner = double(1 << (uBitDepth - 4));
191}
192
193#ifndef GLOBAL_AVERAGING
194  #define GLOBAL_AVERAGING 1 // "global" averaging of a_k across a set instead of one picture
195#endif
196
197#if GLOBAL_AVERAGING
198static double getAveragePictureEnergy (const CPelBuf picOrig, const uint32_t uBitDepth)
199{
200  const double hpEnerPic = 16.0 * sqrt ((3840.0 * 2160.0) / double(picOrig.width * picOrig.height)) * double(1 << uBitDepth);
201
202  return sqrt (hpEnerPic); // square-root of a_pic value
203}
204#endif
205
206static int getGlaringColorQPOffset (Picture* const pcPic, const int ctuAddr, const uint32_t startAddr, const uint32_t boundingAddr,
207                                    const int bitDepth,   uint32_t &avgLumaValue)
208{
209  const PreCalcValues& pcv  = *pcPic->cs->pcv;
210  const ChromaFormat chrFmt = pcPic->chromaFormat;
211  const uint32_t chrWidth   = pcv.maxCUWidth  >> getChannelTypeScaleX (CH_C, chrFmt);
212  const uint32_t chrHeight  = pcv.maxCUHeight >> getChannelTypeScaleY (CH_C, chrFmt);
213  const int      midLevel   = 1 << (bitDepth - 1);
214  int chrValue = MAX_INT;
215  avgLumaValue = (startAddr < boundingAddr) ? 0 : (uint32_t)pcPic->getOrigBuf().Y().computeAvg();
216
217  if (ctuAddr >= 0) // luma
218  {
219    avgLumaValue = (uint32_t)pcPic->m_iOffsetCtu[ctuAddr];
220  }
221  else if (startAddr < boundingAddr)
222  {
223    for (uint32_t ctuTsAddr = startAddr; ctuTsAddr < boundingAddr; ctuTsAddr++)
224    {
225      const uint32_t ctuRsAddr = pcPic->tileMap->getCtuTsToRsAddrMap (ctuTsAddr);
226
227      avgLumaValue += pcPic->m_iOffsetCtu[ctuRsAddr];
228    }
229    avgLumaValue = (avgLumaValue + ((boundingAddr - startAddr) >> 1)) / (boundingAddr - startAddr);
230  }
231
232  for (uint32_t comp = COMPONENT_Cb; comp < MAX_NUM_COMPONENT; comp++)
233  {
234    const ComponentID compID = (ComponentID)comp;
235    int avgCompValue;
236
237    if (ctuAddr >= 0) // chroma
238    {
239      const CompArea chrArea = clipArea (CompArea (compID, chrFmt, Area ((ctuAddr % pcv.widthInCtus) * chrWidth, (ctuAddr / pcv.widthInCtus) * chrHeight, chrWidth, chrHeight)), pcPic->block (compID));
240
241      avgCompValue = pcPic->getOrigBuf (chrArea).computeAvg();
242    }
243    else avgCompValue = pcPic->getOrigBuf (pcPic->block (compID)).computeAvg();
244
245    if (chrValue > avgCompValue) chrValue = avgCompValue; // minimum of the DC offsets
246  }
247  CHECK (chrValue < 0, "DC offset cannot be negative!");
248
249  chrValue = (int)avgLumaValue - chrValue;
250
251  if (chrValue > midLevel) return apprI3Log2 (double (chrValue * chrValue) / double (midLevel * midLevel));
252
253  return 0;
254}
255
256static int applyQPAdaptationChroma (Picture* const pcPic, Slice* const pcSlice, EncCfg* const pcEncCfg, const int sliceQP)
257{
258  const int bitDepth               = pcSlice->getSPS()->getBitDepth (CHANNEL_TYPE_LUMA); // overall image bit-depth
259  double hpEner[MAX_NUM_COMPONENT] = {0.0, 0.0, 0.0};
260  int    optSliceChromaQpOffset[2] = {0, 0};
261  int    savedLumaQP               = -1;
262  uint32_t meanLuma                = MAX_UINT;
263
264  for (uint32_t comp = 0; comp < getNumberValidComponents (pcPic->chromaFormat); comp++)
265  {
266    const ComponentID compID = (ComponentID)comp;
267    const CPelBuf    picOrig = pcPic->getOrigBuf (pcPic->block (compID));
268
269    filterAndCalculateAverageEnergies (picOrig.buf,    picOrig.stride, hpEner[comp],
270                                       picOrig.height, picOrig.width,  bitDepth - (isChroma (compID) ? 1 : 0));
271    if (isChroma (compID))
272    {
273      const int  adaptChromaQPOffset = 2.0 * hpEner[comp] <= hpEner[0] ? 0 : apprI3Log2 (2.0 * hpEner[comp] / hpEner[0]);
274
275      if (savedLumaQP < 0)
276      {
277#if GLOBAL_AVERAGING
278        int     averageAdaptedLumaQP = Clip3 (0, MAX_QP, sliceQP + apprI3Log2 (hpEner[0] / getAveragePictureEnergy (pcPic->getOrigBuf().Y(), bitDepth)));
279#else
280        int     averageAdaptedLumaQP = Clip3 (0, MAX_QP, sliceQP); // mean slice QP
281#endif
282
283        averageAdaptedLumaQP += getGlaringColorQPOffset (pcPic, -1 /*ctuRsAddr*/, 0 /*startAddr*/, 0 /*boundingAddr*/, bitDepth, meanLuma);
284
285        if (averageAdaptedLumaQP > MAX_QP
286#if SHARP_LUMA_DELTA_QP
287            && (pcEncCfg->getLumaLevelToDeltaQPMapping().mode != LUMALVL_TO_DQP_NUM_MODES)
288#endif
289            ) averageAdaptedLumaQP = MAX_QP;
290#if SHARP_LUMA_DELTA_QP
291
292        // change mean picture QP index based on picture's average luma value (Sharp)
293        if (pcEncCfg->getLumaLevelToDeltaQPMapping().mode == LUMALVL_TO_DQP_NUM_MODES)
294        {
295          if (meanLuma == MAX_UINT) meanLuma = pcPic->getOrigBuf().Y().computeAvg();
296
297          averageAdaptedLumaQP = Clip3 (0, MAX_QP, averageAdaptedLumaQP + lumaDQPOffset (meanLuma, bitDepth));
298        }
299#endif
300
301        savedLumaQP = averageAdaptedLumaQP;
302      } // savedLumaQP < 0
303
304      const int lumaChromaMappingDQP = savedLumaQP - getScaledChromaQP (savedLumaQP, pcEncCfg->getChromaFormatIdc());
305
306      optSliceChromaQpOffset[comp-1] = std::min (3 + lumaChromaMappingDQP, adaptChromaQPOffset + lumaChromaMappingDQP);
307    }
308  }
309
310  pcEncCfg->setSliceChromaOffsetQpIntraOrPeriodic (pcEncCfg->getSliceChromaOffsetQpPeriodicity(), optSliceChromaQpOffset);
311
312  return savedLumaQP;
313}
314
315#endif // ENABLE_QPA
316
317/**
318 - non-referenced frame marking
319 - QP computation based on temporal structure
320 - lambda computation based on QP
321 - set temporal layer ID and the parameter sets
322 .
323 \param pcPic         picture class
324 \param pocLast       POC of last picture
325 \param pocCurr       current POC
326 \param iNumPicRcvd   number of received pictures
327 \param iGOPid        POC offset for hierarchical structure
328 \param rpcSlice      slice header class
329 \param isField       true for field coding
330 */
331void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr, const int iGOPid, Slice*& rpcSlice, const bool isField
332  , bool isEncodeLtRef
333)
334{
335  double dQP;
336  double dLambda;
337
338  rpcSlice = pcPic->slices[0];
339  rpcSlice->setSliceBits(0);
340  rpcSlice->setPic( pcPic );
341  rpcSlice->initSlice();
342  int multipleFactor = m_pcCfg->getUseCompositeRef() ? 2 : 1;
343  if (m_pcCfg->getUseCompositeRef() && isEncodeLtRef)
344  {
345    rpcSlice->setPicOutputFlag(false);
346  }
347  else
348  {
349    rpcSlice->setPicOutputFlag(true);
350  }
351  rpcSlice->setPOC( pocCurr );
352  rpcSlice->setDepQuantEnabledFlag( m_pcCfg->getDepQuantEnabledFlag() );
353#if HEVC_USE_SIGN_HIDING
354  rpcSlice->setSignDataHidingEnabledFlag( m_pcCfg->getSignDataHidingEnabledFlag() );
355#endif
356
357#if SHARP_LUMA_DELTA_QP
358  pcPic->fieldPic = isField;
359  m_gopID = iGOPid;
360#endif
361
362  // depth computation based on GOP size
363  int depth;
364  {
365    int poc = rpcSlice->getPOC();
366    if(isField)
367    {
368      poc = (poc/2) % (m_pcCfg->getGOPSize()/2);
369    }
370    else
371    {
372      poc = poc % (m_pcCfg->getGOPSize() * multipleFactor);
373    }
374
375    if ( poc == 0 )
376    {
377      depth = 0;
378    }
379    else
380    {
381      int step = m_pcCfg->getGOPSize() * multipleFactor;
382      depth    = 0;
383      for( int i=step>>1; i>=1; i>>=1 )
384      {
385        for (int j = i; j<(m_pcCfg->getGOPSize() * multipleFactor); j += step)
386        {
387          if ( j == poc )
388          {
389            i=0;
390            break;
391          }
392        }
393        step >>= 1;
394        depth++;
395      }
396    }
397
398    if(m_pcCfg->getHarmonizeGopFirstFieldCoupleEnabled() && poc != 0)
399    {
400      if (isField && ((rpcSlice->getPOC() % 2) == 1))
401      {
402        depth++;
403      }
404    }
405  }
406
407  // slice type
408  SliceType eSliceType;
409
410  eSliceType=B_SLICE;
411  if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled())
412  {
413    if(m_pcCfg->getDecodingRefreshType() == 3)
414    {
415      eSliceType = (pocLast == 0 || pocCurr % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
416    }
417    else
418    {
419      eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
420    }
421  }
422
423  rpcSlice->setSliceType    ( eSliceType );
424
425  // ------------------------------------------------------------------------------------------------------------------
426  // Non-referenced frame marking
427  // ------------------------------------------------------------------------------------------------------------------
428
429#if !JVET_M0101_HLS
430  if(pocLast == 0)
431  {
432    rpcSlice->setTemporalLayerNonReferenceFlag(false);
433  }
434  else
435  {
436    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
437  }
438#endif
439  pcPic->referenced = true;
440
441  // ------------------------------------------------------------------------------------------------------------------
442  // QP setting
443  // ------------------------------------------------------------------------------------------------------------------
444
445#if X0038_LAMBDA_FROM_QP_CAPABILITY
446  dQP = m_pcCfg->getQPForPicture(iGOPid, rpcSlice);
447#else
448  dQP = m_pcCfg->getBaseQP();
449  if(eSliceType!=I_SLICE)
450  {
451#if SHARP_LUMA_DELTA_QP
452    if (!(( m_pcCfg->getMaxDeltaQP() == 0) && (!m_pcCfg->getLumaLevelToDeltaQPMapping().isEnabled()) && (dQP == -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA) ) && (rpcSlice->getPPS()->getTransquantBypassEnabledFlag())))
453#else
454    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA) ) && (rpcSlice->getPPS()->getTransquantBypassEnabledFlag())))
455#endif
456    {
457      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
458    }
459  }
460
461  // modify QP
462  const int* pdQPs = m_pcCfg->getdQPs();
463  if ( pdQPs )
464  {
465    dQP += pdQPs[ rpcSlice->getPOC() ];
466  }
467
468  if (m_pcCfg->getCostMode()==COST_LOSSLESS_CODING)
469  {
470    dQP=LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP;
471    m_pcCfg->setDeltaQpRD(0);
472  }
473#endif
474
475  // ------------------------------------------------------------------------------------------------------------------
476  // Lambda computation
477  // ------------------------------------------------------------------------------------------------------------------
478
479#if X0038_LAMBDA_FROM_QP_CAPABILITY
480  const int temporalId=m_pcCfg->getGOPEntry(iGOPid).m_temporalId;
481#if !SHARP_LUMA_DELTA_QP
482  const std::vector<double> &intraLambdaModifiers=m_pcCfg->getIntraLambdaModifier();
483#endif
484#endif
485  int iQP;
486  double dOrigQP = dQP;
487
488  // pre-compute lambda and QP values for all possible QP candidates
489  for ( int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
490  {
491    // compute QP value
492    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
493#if SHARP_LUMA_DELTA_QP
494    dLambda = calculateLambda(rpcSlice, iGOPid, depth, dQP, dQP, iQP );
495#else
496    // compute lambda value
497    int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
498    int    SHIFT_QP = 12;
499
500    int    bitdepth_luma_qp_scale =
501      6
502      * (rpcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8
503         - DISTORTION_PRECISION_ADJUSTMENT(rpcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA)));
504    double qp_temp = (double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
505#if FULL_NBIT
506    double qp_temp_orig = (double) dQP - SHIFT_QP;
507#endif
508    // Case #1: I or P-slices (key-frame)
509    double dQPFactor = m_pcCfg->getGOPEntry(iGOPid).m_QPFactor;
510    if ( eSliceType==I_SLICE )
511    {
512      if (m_pcCfg->getIntraQpFactor()>=0.0 && m_pcCfg->getGOPEntry(iGOPid).m_sliceType != I_SLICE)
513      {
514        dQPFactor=m_pcCfg->getIntraQpFactor();
515      }
516      else
517      {
518#if X0038_LAMBDA_FROM_QP_CAPABILITY
519        if(m_pcCfg->getLambdaFromQPEnable())
520        {
521          dQPFactor=0.57;
522        }
523        else
524        {
525#endif
526        double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(double)(isField ? NumberBFrames/2 : NumberBFrames) );
527
528        dQPFactor=0.57*dLambda_scale;
529#if X0038_LAMBDA_FROM_QP_CAPABILITY
530        }
531#endif
532      }
533    }
534#if X0038_LAMBDA_FROM_QP_CAPABILITY
535    else if( m_pcCfg->getLambdaFromQPEnable() )
536    {
537      dQPFactor=0.57;
538    }
539#endif
540
541    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
542
543#if X0038_LAMBDA_FROM_QP_CAPABILITY
544    if(!m_pcCfg->getLambdaFromQPEnable() && depth>0)
545#else
546    if ( depth>0 )
547#endif
548    {
549#if FULL_NBIT
550        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
551#else
552        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
553#endif
554    }
555
556    // if hadamard is used in ME process
557    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
558    {
559      dLambda *= 0.95;
560    }
561
562#if X0038_LAMBDA_FROM_QP_CAPABILITY
563    double lambdaModifier;
564    if( rpcSlice->getSliceType( ) != I_SLICE || intraLambdaModifiers.empty())
565    {
566      lambdaModifier = m_pcCfg->getLambdaModifier( temporalId );
567    }
568    else
569    {
570      lambdaModifier = intraLambdaModifiers[ (temporalId < intraLambdaModifiers.size()) ? temporalId : (intraLambdaModifiers.size()-1) ];
571    }
572    dLambda *= lambdaModifier;
573#endif
574
575    iQP = Clip3( -rpcSlice->getSPS()->getQpBDOffset( CHANNEL_TYPE_LUMA ), MAX_QP, (int) floor( dQP + 0.5 ) );
576#endif
577
578    m_vdRdPicLambda[iDQpIdx] = dLambda;
579    m_vdRdPicQp    [iDQpIdx] = dQP;
580    m_viRdPicQp    [iDQpIdx] = iQP;
581  }
582
583  // obtain dQP = 0 case
584  dLambda = m_vdRdPicLambda[0];
585  dQP     = m_vdRdPicQp    [0];
586  iQP     = m_viRdPicQp    [0];
587
588#if !X0038_LAMBDA_FROM_QP_CAPABILITY
589  const int temporalId=m_pcCfg->getGOPEntry(iGOPid).m_temporalId;
590  const std::vector<double> &intraLambdaModifiers=m_pcCfg->getIntraLambdaModifier();
591#endif
592
593#if W0038_CQP_ADJ
594 #if ENABLE_QPA
595  m_adaptedLumaQP = -1;
596
597  if ((m_pcCfg->getUsePerceptQPA() || m_pcCfg->getSliceChromaOffsetQpPeriodicity() > 0) && !m_pcCfg->getUseRateCtrl() && rpcSlice->getPPS()->getSliceChromaQpFlag() &&
598      (rpcSlice->isIntra() || (m_pcCfg->getSliceChromaOffsetQpPeriodicity() > 0 && (rpcSlice->getPOC() % m_pcCfg->getSliceChromaOffsetQpPeriodicity()) == 0)))
599  {
600    m_adaptedLumaQP = applyQPAdaptationChroma (pcPic, rpcSlice, m_pcCfg, iQP);
601  }
602 #endif
603  if(rpcSlice->getPPS()->getSliceChromaQpFlag())
604  {
605    const bool bUseIntraOrPeriodicOffset = (rpcSlice->isIntra() && !rpcSlice->getSPS()->getIBCFlag()) || (m_pcCfg->getSliceChromaOffsetQpPeriodicity() > 0 && (rpcSlice->getPOC() % m_pcCfg->getSliceChromaOffsetQpPeriodicity()) == 0);
606    int cbQP = bUseIntraOrPeriodicOffset ? m_pcCfg->getSliceChromaOffsetQpIntraOrPeriodic(false) : m_pcCfg->getGOPEntry(iGOPid).m_CbQPoffset;
607    int crQP = bUseIntraOrPeriodicOffset ? m_pcCfg->getSliceChromaOffsetQpIntraOrPeriodic(true)  : m_pcCfg->getGOPEntry(iGOPid).m_CrQPoffset;
608
609    cbQP = Clip3( -12, 12, cbQP + rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb) ) - rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb);
610    crQP = Clip3( -12, 12, crQP + rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr) ) - rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr);
611    rpcSlice->setSliceChromaQpDelta(COMPONENT_Cb, Clip3( -12, 12, cbQP));
612    CHECK(!(rpcSlice->getSliceChromaQpDelta(COMPONENT_Cb)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb)<=12 && rpcSlice->getSliceChromaQpDelta(COMPONENT_Cb)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb)>=-12), "Unspecified error");
613    rpcSlice->setSliceChromaQpDelta(COMPONENT_Cr, Clip3( -12, 12, crQP));
614    CHECK(!(rpcSlice->getSliceChromaQpDelta(COMPONENT_Cr)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr)<=12 && rpcSlice->getSliceChromaQpDelta(COMPONENT_Cr)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr)>=-12), "Unspecified error");
615  }
616  else
617  {
618    rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
619    rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
620#if JVET_N0054_JOINT_CHROMA
621    rpcSlice->setSliceChromaQpDelta( JOINT_CbCr, 0 );
622#endif
623  }
624#endif
625
626#if !X0038_LAMBDA_FROM_QP_CAPABILITY
627  double lambdaModifier;
628  if( rpcSlice->getSliceType( ) != I_SLICE || intraLambdaModifiers.empty())
629  {
630    lambdaModifier = m_pcCfg->getLambdaModifier( temporalId );
631  }
632  else
633  {
634    lambdaModifier = intraLambdaModifiers[ (temporalId < intraLambdaModifiers.size()) ? temporalId : (intraLambdaModifiers.size()-1) ];
635  }
636
637  dLambda *= lambdaModifier;
638#endif
639
640  setUpLambda(rpcSlice, dLambda, iQP);
641
642#if WCG_EXT
643  // cost = Distortion + Lambda*R,
644  // when QP is adjusted by luma, distortion is changed, so we have to adjust lambda to match the distortion, then the cost function becomes
645  // costA = Distortion + AdjustedLambda * R          -- currently, costA is still used when calculating intermediate cost of using SAD, HAD, resisual etc.
646  // an alternative way is to weight the distortion to before the luma QP adjustment, then the cost function becomes
647  // costB = weightedDistortion + Lambda * R          -- currently, costB is used to calculat final cost, and when DF_FUNC is DF_DEFAULT
648  m_pcRdCost->saveUnadjustedLambda();
649#endif
650
651  if (m_pcCfg->getFastMEForGenBLowDelayEnabled())
652  {
653    // restore original slice type
654
655    if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled())
656    {
657      if(m_pcCfg->getDecodingRefreshType() == 3)
658      {
659        eSliceType = (pocLast == 0 || (pocCurr) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
660      }
661      else
662      {
663        eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % (m_pcCfg->getIntraPeriod() * multipleFactor) == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
664      }
665    }
666
667    rpcSlice->setSliceType        ( eSliceType );
668  }
669
670  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
671  {
672    dQP = xGetQPValueAccordingToLambda( dLambda );
673    iQP = Clip3( -rpcSlice->getSPS()->getQpBDOffset( CHANNEL_TYPE_LUMA ), MAX_QP, (int) floor( dQP + 0.5 ) );
674  }
675
676  rpcSlice->setSliceQp           ( iQP );
677  rpcSlice->setSliceQpDelta      ( 0 );
678#if !W0038_CQP_ADJ
679  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
680  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
681#if JVET_N0054_JOINT_CHROMA
682  rpcSlice->setSliceChromaQpDelta( JOINT_CbCr,   0 );
683#endif
684#endif
685  rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getPpsRangeExtension().getChromaQpOffsetListEnabledFlag() );
686  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
687  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
688
689  if ( m_pcCfg->getDeblockingFilterMetric() )
690  {
691    rpcSlice->setDeblockingFilterOverrideFlag(true);
692    rpcSlice->setDeblockingFilterDisable(false);
693    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
694    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
695  }
696  else if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
697  {
698    rpcSlice->setDeblockingFilterOverrideFlag( rpcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() );
699    rpcSlice->setDeblockingFilterDisable( rpcSlice->getPPS()->getPPSDeblockingFilterDisabledFlag() );
700    if ( !rpcSlice->getDeblockingFilterDisable())
701    {
702      if ( rpcSlice->getDeblockingFilterOverrideFlag() && eSliceType!=I_SLICE)
703      {
704        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
705        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
706      }
707      else
708      {
709        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
710        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
711      }
712    }
713  }
714  else
715  {
716    rpcSlice->setDeblockingFilterOverrideFlag( false );
717    rpcSlice->setDeblockingFilterDisable( false );
718    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
719    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
720  }
721
722  rpcSlice->setDepth            ( depth );
723
724  pcPic->layer =  temporalId;
725  if(eSliceType==I_SLICE)
726  {
727    pcPic->layer = 0;
728  }
729  rpcSlice->setTLayer( pcPic->layer );
730
731  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
732  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
733#if HEVC_DEPENDENT_SLICES
734  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
735  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
736#endif
737  rpcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()      );
738  rpcSlice->setMaxNumAffineMergeCand( m_pcCfg->getMaxNumAffineMergeCand() );
739#if JVET_N0400_SIGNAL_TRIANGLE_CAND_NUM
740  rpcSlice->setMaxNumTriangleCand   ( m_pcCfg->getMaxNumTriangleCand() );
741#endif
742  rpcSlice->setSplitConsOverrideFlag(false);
743  rpcSlice->setMinQTSize( rpcSlice->getSPS()->getMinQTSize(eSliceType));
744  rpcSlice->setMaxBTDepth( rpcSlice->isIntra() ? rpcSlice->getSPS()->getMaxBTDepthI() : rpcSlice->getSPS()->getMaxBTDepth() );
745  rpcSlice->setMaxBTSize( rpcSlice->isIntra() ? rpcSlice->getSPS()->getMaxBTSizeI() : rpcSlice->getSPS()->getMaxBTSize() );
746  rpcSlice->setMaxTTSize( rpcSlice->isIntra() ? rpcSlice->getSPS()->getMaxTTSizeI() : rpcSlice->getSPS()->getMaxTTSize() );
747  if ( eSliceType == I_SLICE && rpcSlice->getSPS()->getUseDualITree() )
748  {
749    rpcSlice->setMinQTSizeIChroma( rpcSlice->getSPS()->getMinQTSize(eSliceType, CHANNEL_TYPE_CHROMA) );
750    rpcSlice->setMaxBTDepthIChroma( rpcSlice->getSPS()->getMaxBTDepthIChroma() );
751    rpcSlice->setMaxBTSizeIChroma( rpcSlice->getSPS()->getMaxBTSizeIChroma() );
752    rpcSlice->setMaxTTSizeIChroma( rpcSlice->getSPS()->getMaxTTSizeIChroma() );
753  }
754#if JVET_N0329_IBC_SEARCH_IMP
755  rpcSlice->setDisableSATDForRD(false);
756#endif
757}
758
759
760#if SHARP_LUMA_DELTA_QP
761double EncSlice::calculateLambda( const Slice*     slice,
762                                  const int        GOPid, // entry in the GOP table
763                                  const int        depth, // slice GOP hierarchical depth.
764                                  const double     refQP, // initial slice-level QP
765                                  const double     dQP,   // initial double-precision QP
766                                        int       &iQP )  // returned integer QP.
767{
768  enum   SliceType eSliceType    = slice->getSliceType();
769  const  bool      isField       = slice->getPic()->fieldPic;
770  const  int       NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
771  const  int       SHIFT_QP      = 12;
772#if X0038_LAMBDA_FROM_QP_CAPABILITY
773  const int temporalId=m_pcCfg->getGOPEntry(GOPid).m_temporalId;
774  const std::vector<double> &intraLambdaModifiers=m_pcCfg->getIntraLambdaModifier();
775#endif
776
777  int bitdepth_luma_qp_scale = 6
778                               * (slice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8
779                                  - DISTORTION_PRECISION_ADJUSTMENT(slice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA)));
780  double qp_temp = dQP + bitdepth_luma_qp_scale - SHIFT_QP;
781  // Case #1: I or P-slices (key-frame)
782  double dQPFactor = m_pcCfg->getGOPEntry(GOPid).m_QPFactor;
783  if ( eSliceType==I_SLICE )
784  {
785    if (m_pcCfg->getIntraQpFactor()>=0.0 && m_pcCfg->getGOPEntry(GOPid).m_sliceType != I_SLICE)
786    {
787      dQPFactor=m_pcCfg->getIntraQpFactor();
788    }
789    else
790    {
791#if X0038_LAMBDA_FROM_QP_CAPABILITY
792      if(m_pcCfg->getLambdaFromQPEnable())
793      {
794        dQPFactor=0.57;
795      }
796      else
797      {
798#endif
799        double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(double)(isField ? NumberBFrames/2 : NumberBFrames) );
800        dQPFactor=0.57*dLambda_scale;
801#if X0038_LAMBDA_FROM_QP_CAPABILITY
802      }
803#endif
804    }
805  }
806#if X0038_LAMBDA_FROM_QP_CAPABILITY
807  else if( m_pcCfg->getLambdaFromQPEnable() )
808  {
809    dQPFactor=0.57;
810  }
811#endif
812
813  double dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
814
815#if X0038_LAMBDA_FROM_QP_CAPABILITY
816  if( !(m_pcCfg->getLambdaFromQPEnable()) && depth>0 )
817#else
818  if ( depth>0 )
819#endif
820  {
821    double qp_temp_ref = refQP + bitdepth_luma_qp_scale - SHIFT_QP;
822    dLambda *= Clip3(2.00, 4.00, (qp_temp_ref / 6.0));   // (j == B_SLICE && p_cur_frm->layer != 0 )
823  }
824
825  // if hadamard is used in ME process
826  if ( !m_pcCfg->getUseHADME() && slice->getSliceType( ) != I_SLICE )
827  {
828    dLambda *= 0.95;
829  }
830
831#if X0038_LAMBDA_FROM_QP_CAPABILITY
832  double lambdaModifier;
833  if( eSliceType != I_SLICE || intraLambdaModifiers.empty())
834  {
835    lambdaModifier = m_pcCfg->getLambdaModifier( temporalId );
836  }
837  else
838  {
839    lambdaModifier = intraLambdaModifiers[ (temporalId < intraLambdaModifiers.size()) ? temporalId : (intraLambdaModifiers.size()-1) ];
840  }
841  dLambda *= lambdaModifier;
842#endif
843
844  iQP = Clip3( -slice->getSPS()->getQpBDOffset( CHANNEL_TYPE_LUMA ), MAX_QP, (int) floor( dQP + 0.5 ) );
845
846  if( m_pcCfg->getDepQuantEnabledFlag() )
847  {
848    dLambda *= pow( 2.0, 0.25/3.0 ); // slight lambda adjustment for dependent quantization (due to different slope of quantizer)
849  }
850
851  // NOTE: the lambda modifiers that are sometimes applied later might be best always applied in here.
852  return dLambda;
853}
854#endif
855
856void EncSlice::resetQP( Picture* pic, int sliceQP, double lambda )
857{
858  Slice* slice = pic->slices[0];
859
860  // store lambda
861  slice->setSliceQp( sliceQP );
862  setUpLambda(slice, lambda, sliceQP);
863}
864
865#if ENABLE_QPA
866static bool applyQPAdaptation (Picture* const pcPic,       Slice* const pcSlice,        const PreCalcValues& pcv,
867                               const uint32_t startAddr,   const uint32_t boundingAddr, const bool useSharpLumaDQP,
868                               const bool useFrameWiseQPA, const int previouslyAdaptedLumaQP = -1)
869{
870  const int  bitDepth    = pcSlice->getSPS()->getBitDepth (CHANNEL_TYPE_LUMA);
871  const int  iQPIndex    = pcSlice->getSliceQp(); // initial QP index for current slice, used in following loops
872  const TileMap& tileMap = *pcPic->tileMap;
873  bool   sliceQPModified = false;
874  uint32_t   meanLuma    = MAX_UINT;
875  double     hpEnerAvg   = 0.0;
876
877#if GLOBAL_AVERAGING
878  if (!useFrameWiseQPA || previouslyAdaptedLumaQP < 0)  // mean visual activity value and luma value in each CTU
879#endif
880  {
881    for (uint32_t ctuTsAddr = startAddr; ctuTsAddr < boundingAddr; ctuTsAddr++)
882    {
883      const uint32_t ctuRsAddr  = tileMap.getCtuTsToRsAddrMap (ctuTsAddr);
884      const Position pos ((ctuRsAddr % pcv.widthInCtus) * pcv.maxCUWidth, (ctuRsAddr / pcv.widthInCtus) * pcv.maxCUHeight);
885      const CompArea ctuArea    = clipArea (CompArea (COMPONENT_Y, pcPic->chromaFormat, Area (pos.x, pos.y, pcv.maxCUWidth, pcv.maxCUHeight)), pcPic->Y());
886      const CompArea fltArea    = clipArea (CompArea (COMPONENT_Y, pcPic->chromaFormat, Area (pos.x > 0 ? pos.x - 1 : 0, pos.y > 0 ? pos.y - 1 : 0, pcv.maxCUWidth + (pos.x > 0 ? 2 : 1), pcv.maxCUHeight + (pos.y > 0 ? 2 : 1))), pcPic->Y());
887      const CPelBuf  picOrig    = pcPic->getOrigBuf (fltArea);
888      double hpEner = 0.0;
889
890      filterAndCalculateAverageEnergies (picOrig.buf,    picOrig.stride, hpEner,
891                                         picOrig.height, picOrig.width,  bitDepth);
892      hpEnerAvg += hpEner;
893      pcPic->m_uEnerHpCtu[ctuRsAddr] = hpEner;
894      pcPic->m_iOffsetCtu[ctuRsAddr] = pcPic->getOrigBuf (ctuArea).computeAvg();
895    }
896
897    hpEnerAvg /= double (boundingAddr - startAddr);
898  }
899#if GLOBAL_AVERAGING
900  const double hpEnerPic = 1.0 / getAveragePictureEnergy (pcPic->getOrigBuf().Y(), bitDepth);  // inverse, speed
901#else
902  const double hpEnerPic = 1.0 / hpEnerAvg; // speedup: multiply instead of divide in loop below; 1.0 for tuning
903#endif
904
905  if (useFrameWiseQPA || (iQPIndex >= MAX_QP))
906  {
907    int iQPFixed = (previouslyAdaptedLumaQP < 0) ? Clip3 (0, MAX_QP, iQPIndex + apprI3Log2 (hpEnerAvg * hpEnerPic)) : previouslyAdaptedLumaQP;
908
909    if (isChromaEnabled (pcPic->chromaFormat) && (iQPIndex < MAX_QP) && (previouslyAdaptedLumaQP < 0))
910    {
911      iQPFixed += getGlaringColorQPOffset (pcPic, -1 /*ctuRsAddr*/, startAddr, boundingAddr, bitDepth, meanLuma);
912
913      if (iQPFixed > MAX_QP
914#if SHARP_LUMA_DELTA_QP
915          && !useSharpLumaDQP
916#endif
917          ) iQPFixed = MAX_QP;
918    }
919#if SHARP_LUMA_DELTA_QP
920
921    // change new fixed QP based on average CTU luma value (Sharp)
922    if (useSharpLumaDQP && (iQPIndex < MAX_QP) && (previouslyAdaptedLumaQP < 0))
923    {
924      if (meanLuma == MAX_UINT) // collect picture mean luma value
925      {
926        meanLuma = 0;
927
928        for (uint32_t ctuTsAddr = startAddr; ctuTsAddr < boundingAddr; ctuTsAddr++)
929        {
930          const uint32_t ctuRsAddr = tileMap.getCtuTsToRsAddrMap (ctuTsAddr);
931
932          meanLuma += pcPic->m_iOffsetCtu[ctuRsAddr];  // CTU mean
933        }
934        meanLuma = (meanLuma + ((boundingAddr - startAddr) >> 1)) / (boundingAddr - startAddr);
935      }
936      iQPFixed = Clip3 (0, MAX_QP, iQPFixed + lumaDQPOffset (meanLuma, bitDepth));
937    }
938#endif
939
940    if (iQPIndex >= MAX_QP) iQPFixed = MAX_QP;
941    else
942    if (iQPFixed != iQPIndex)
943    {
944      const double* oldLambdas = pcSlice->getLambdas();
945      const double  corrFactor = pow (2.0, double(iQPFixed - iQPIndex) / 3.0);
946      const double  newLambdas[MAX_NUM_COMPONENT] = {oldLambdas[0] * corrFactor, oldLambdas[1] * corrFactor, oldLambdas[2] * corrFactor};
947
948      CHECK (iQPIndex != pcSlice->getSliceQpBase(), "Invalid slice QP!");
949      pcSlice->setLambdas (newLambdas);
950      pcSlice->setSliceQp (iQPFixed); // update the slice/base QPs
951      pcSlice->setSliceQpBase (iQPFixed);
952
953      sliceQPModified = true;
954    }
955
956    for (uint32_t ctuTsAddr = startAddr; ctuTsAddr < boundingAddr; ctuTsAddr++)
957    {
958      const uint32_t ctuRsAddr = tileMap.getCtuTsToRsAddrMap (ctuTsAddr);
959
960      pcPic->m_iOffsetCtu[ctuRsAddr] = (Pel)iQPFixed; // fixed QPs
961    }
962  }
963  else // CTU-wise QPA
964  {
965    for (uint32_t ctuTsAddr = startAddr; ctuTsAddr < boundingAddr; ctuTsAddr++)
966    {
967      const uint32_t ctuRsAddr = tileMap.getCtuTsToRsAddrMap (ctuTsAddr);
968
969      int iQPAdapt = Clip3 (0, MAX_QP, iQPIndex + apprI3Log2 (pcPic->m_uEnerHpCtu[ctuRsAddr] * hpEnerPic));
970
971      if (pcv.widthInCtus > 1) // try to enforce CTU SNR greater than zero dB
972      {
973        meanLuma = (uint32_t)pcPic->m_iOffsetCtu[ctuRsAddr];
974
975        if (isChromaEnabled (pcPic->chromaFormat))
976        {
977          iQPAdapt += getGlaringColorQPOffset (pcPic, (int)ctuRsAddr, startAddr, boundingAddr, bitDepth, meanLuma);
978
979          if (iQPAdapt > MAX_QP
980#if SHARP_LUMA_DELTA_QP
981              && !useSharpLumaDQP
982#endif
983              ) iQPAdapt = MAX_QP;
984          CHECK (meanLuma != (uint32_t)pcPic->m_iOffsetCtu[ctuRsAddr], "luma DC offsets don't match");
985        }
986#if SHARP_LUMA_DELTA_QP
987
988        // change adaptive QP based on mean CTU luma value (Sharp)
989        if (useSharpLumaDQP)
990        {
991 #if ENABLE_QPA_SUB_CTU
992          pcPic->m_uEnerHpCtu[ctuRsAddr] = (double)meanLuma; // for sub-CTU QPA
993 #endif
994          iQPAdapt = Clip3 (0, MAX_QP, iQPAdapt + lumaDQPOffset (meanLuma, bitDepth));
995        }
996
997#endif
998#if JVET_N0246_MODIFIED_QUANTSCALES
999        const uint32_t uRefScale  = g_invQuantScales[0][iQPAdapt % 6] << ((iQPAdapt / 6) + bitDepth - 4);
1000#else
1001        const uint32_t uRefScale  = g_invQuantScales[iQPAdapt % 6] << ((iQPAdapt / 6) + bitDepth - 4);
1002#endif
1003        const CompArea subArea    = clipArea (CompArea (COMPONENT_Y, pcPic->chromaFormat, Area ((ctuRsAddr % pcv.widthInCtus) * pcv.maxCUWidth, (ctuRsAddr / pcv.widthInCtus) * pcv.maxCUHeight, pcv.maxCUWidth, pcv.maxCUHeight)), pcPic->Y());
1004        const Pel*     pSrc       = pcPic->getOrigBuf (subArea).buf;
1005        const SizeType iSrcStride = pcPic->getOrigBuf (subArea).stride;
1006        const SizeType iSrcHeight = pcPic->getOrigBuf (subArea).height;
1007        const SizeType iSrcWidth  = pcPic->getOrigBuf (subArea).width;
1008        uint32_t uAbsDCless = 0;
1009
1010        // compute sum of absolute DC-less (high-pass) luma values
1011        for (SizeType h = 0; h < iSrcHeight; h++)
1012        {
1013          for (SizeType w = 0; w < iSrcWidth; w++)
1014          {
1015            uAbsDCless += (uint32_t)abs (pSrc[w] - (Pel)meanLuma);
1016          }
1017          pSrc += iSrcStride;
1018        }
1019
1020        if (iSrcHeight >= 64 || iSrcWidth >= 64)  // normalization
1021        {
1022          const uint64_t blockSize = uint64_t(iSrcWidth * iSrcHeight);
1023
1024          uAbsDCless = uint32_t((uint64_t(uAbsDCless) * 64*64 + (blockSize >> 1)) / blockSize);
1025        }
1026
1027        if (uAbsDCless < 64*64) uAbsDCless = 64*64;  // limit to 1
1028
1029        // reduce QP index if CTU would be fully quantized to zero
1030        if (uAbsDCless < uRefScale)
1031        {
1032          const int limit  = std::min (0, ((iQPIndex + 4) >> 3) - 6);
1033          const int redVal = std::max (limit, apprI3Log2 ((double)uAbsDCless / (double)uRefScale));
1034
1035          iQPAdapt = std::max (0, iQPAdapt + redVal);
1036        }
1037      }
1038
1039      pcPic->m_iOffsetCtu[ctuRsAddr] = (Pel)iQPAdapt; // adapted QPs
1040
1041#if ENABLE_QPA_SUB_CTU
1042      if (pcv.widthInCtus > 1 && pcSlice->getPPS()->getCuQpDeltaSubdiv() == 0)  // reduce local DQP rate peaks
1043#elif ENABLE_QPA_SUB_CTU
1044      if (pcv.widthInCtus > 1 && pcSlice->getPPS()->getMaxCuDQPDepth() == 0)  // reduce local DQP rate peaks
1045#else
1046      if (pcv.widthInCtus > 1) // try to reduce local bitrate peaks via minimum smoothing of the adapted QPs
1047#endif
1048      {
1049        iQPAdapt = ctuRsAddr % pcv.widthInCtus; // horizontal offset
1050        if (iQPAdapt == 0)
1051        {
1052          iQPAdapt = (ctuRsAddr > 1) ? pcPic->m_iOffsetCtu[ctuRsAddr - 2] : 0;
1053        }
1054        else // iQPAdapt >= 1
1055        {
1056          iQPAdapt = (iQPAdapt > 1) ? std::min (pcPic->m_iOffsetCtu[ctuRsAddr - 2], pcPic->m_iOffsetCtu[ctuRsAddr]) : pcPic->m_iOffsetCtu[ctuRsAddr];
1057        }
1058        if (ctuRsAddr > pcv.widthInCtus)
1059        {
1060          iQPAdapt = std::min (iQPAdapt, (int)pcPic->m_iOffsetCtu[ctuRsAddr - 1 - pcv.widthInCtus]);
1061        }
1062        if ((ctuRsAddr > 0) && (pcPic->m_iOffsetCtu[ctuRsAddr - 1] < (Pel)iQPAdapt))
1063        {
1064          pcPic->m_iOffsetCtu[ctuRsAddr - 1] = (Pel)iQPAdapt;
1065        }
1066        if ((ctuTsAddr == boundingAddr - 1) && (ctuRsAddr > pcv.widthInCtus)) // last CTU in the given slice
1067        {
1068          iQPAdapt = std::min (pcPic->m_iOffsetCtu[ctuRsAddr - 1], pcPic->m_iOffsetCtu[ctuRsAddr - pcv.widthInCtus]);
1069          if (pcPic->m_iOffsetCtu[ctuRsAddr] < (Pel)iQPAdapt)
1070          {
1071            pcPic->m_iOffsetCtu[ctuRsAddr] = (Pel)iQPAdapt;
1072          }
1073        }
1074      }
1075    } // end iteration over all CTUs in current slice
1076  }
1077
1078  return sliceQPModified;
1079}
1080
1081#if ENABLE_QPA_SUB_CTU
1082static int applyQPAdaptationSubCtu (CodingStructure &cs, const UnitArea ctuArea, const uint32_t ctuAddr, const bool useSharpLumaDQP)
1083{
1084  const PreCalcValues &pcv = *cs.pcv;
1085  const Picture     *pcPic = cs.picture;
1086  const int       bitDepth = cs.slice->getSPS()->getBitDepth (CHANNEL_TYPE_LUMA); // overall image bit-depth
1087  const int   adaptedCtuQP = pcPic ? pcPic->m_iOffsetCtu[ctuAddr] : cs.slice->getSliceQpBase();
1088
1089  if (!pcPic || cs.pps->getCuQpDeltaSubdiv() == 0) return adaptedCtuQP;
1090
1091  for (unsigned addr = 0; addr < cs.picture->m_subCtuQP.size(); addr++)
1092  {
1093    cs.picture->m_subCtuQP[addr] = (int8_t)adaptedCtuQP;
1094  }
1095  if (cs.slice->getSliceQp() < MAX_QP && pcv.widthInCtus > 1)
1096  {
1097#if SHARP_LUMA_DELTA_QP
1098    const int   lumaCtuDQP = useSharpLumaDQP ? lumaDQPOffset ((uint32_t)pcPic->m_uEnerHpCtu[ctuAddr], bitDepth) : 0;
1099#endif
1100#if MAX_TB_SIZE_SIGNALLING
1101    const unsigned     mts = std::min (cs.sps->getMaxTbSize(), pcv.maxCUWidth);
1102#else
1103    const unsigned     mts = std::min<uint32_t> (MAX_TB_SIZEY, pcv.maxCUWidth);
1104#endif
1105    const unsigned mtsLog2 = (unsigned)g_aucLog2[mts];
1106    const unsigned  stride = pcv.maxCUWidth >> mtsLog2;
1107    unsigned numAct = 0;    // number of block activities
1108    double   sumAct = 0.0; // sum of all block activities
1109    double   subAct[16];   // individual block activities
1110#if SHARP_LUMA_DELTA_QP
1111    uint32_t subMLV[16];   // individual mean luma values
1112#endif
1113
1114    CHECK (mts * 4 < pcv.maxCUWidth || mts * 4 < pcv.maxCUHeight, "max. transform size is too small for given CTU size");
1115
1116    for (unsigned h = 0; h < (pcv.maxCUHeight >> mtsLog2); h++)
1117    {
1118      for (unsigned w = 0; w < stride; w++)
1119      {
1120        const unsigned addr    = w + h * stride;
1121        const PosType  x       = ctuArea.lx() + w * mts;
1122        const PosType  y       = ctuArea.ly() + h * mts;
1123        const CompArea fltArea = clipArea (CompArea (COMPONENT_Y, pcPic->chromaFormat, Area (x > 0 ? x - 1 : 0, y > 0 ? y - 1 : 0, mts + (x > 0 ? 2 : 1), mts + (y > 0 ? 2 : 1))), pcPic->Y());
1124        const CPelBuf  picOrig = pcPic->getOrigBuf (fltArea);
1125
1126        if (x >= pcPic->lwidth() || y >= pcPic->lheight())
1127        {
1128          continue;
1129        }
1130        filterAndCalculateAverageEnergies (picOrig.buf,    picOrig.stride, subAct[addr],
1131                                           picOrig.height, picOrig.width,  bitDepth);
1132        numAct++;
1133        sumAct += subAct[addr];
1134#if SHARP_LUMA_DELTA_QP
1135
1136        if (useSharpLumaDQP)
1137        {
1138          const CompArea subArea = clipArea (CompArea (COMPONENT_Y, pcPic->chromaFormat, Area (x, y, mts, mts)), pcPic->Y());
1139
1140          subMLV[addr] = pcPic->getOrigBuf (subArea).computeAvg();
1141        }
1142#endif
1143      }
1144    }
1145    if (sumAct <= 0.0) return adaptedCtuQP;
1146
1147    sumAct = double(numAct) / sumAct; // 1.0 / (average CTU activity)
1148
1149    for (unsigned h = 0; h < (pcv.maxCUHeight >> mtsLog2); h++)
1150    {
1151      for (unsigned w = 0; w < stride; w++)
1152      {
1153        const unsigned addr = w + h * stride;
1154
1155        if (ctuArea.lx() + w * mts >= pcPic->lwidth() || ctuArea.ly() + h * mts >= pcPic->lheight())
1156        {
1157          continue;
1158        }
1159        cs.picture->m_subCtuQP[addr] = (int8_t)Clip3 (0, MAX_QP, adaptedCtuQP + apprI3Log2 (subAct[addr] * sumAct));
1160#if SHARP_LUMA_DELTA_QP
1161
1162        // change adapted QP based on mean sub-CTU luma value (Sharp)
1163        if (useSharpLumaDQP)
1164        {
1165          cs.picture->m_subCtuQP[addr] = (int8_t)Clip3 (0, MAX_QP, (int)cs.picture->m_subCtuQP[addr] - lumaCtuDQP + lumaDQPOffset (subMLV[addr], bitDepth));
1166        }
1167#endif
1168      }
1169    }
1170  }
1171
1172  return adaptedCtuQP;
1173}
1174#endif // ENABLE_QPA_SUB_CTU
1175#endif // ENABLE_QPA
1176
1177// ====================================================================================================================
1178// Public member functions
1179// ====================================================================================================================
1180
1181//! set adaptive search range based on poc difference
1182void EncSlice::setSearchRange( Slice* pcSlice )
1183{
1184  int iCurrPOC = pcSlice->getPOC();
1185  int iRefPOC;
1186  int iGOPSize = m_pcCfg->getGOPSize();
1187  int iOffset = (iGOPSize >> 1);
1188  int iMaxSR = m_pcCfg->getSearchRange();
1189  int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
1190
1191  for (int iDir = 0; iDir < iNumPredDir; iDir++)
1192  {
1193    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
1194    for (int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
1195    {
1196      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
1197      int newSearchRange = Clip3(m_pcCfg->getMinSearchWindow(), iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
1198      m_pcInterSearch->setAdaptiveSearchRange(iDir, iRefIdx, newSearchRange);
1199#if ENABLE_WPP_PARALLELISM
1200      for( int jId = 1; jId < m_pcLib->getNumCuEncStacks(); jId++ )
1201      {
1202        m_pcLib->getInterSearch( jId )->setAdaptiveSearchRange( iDir, iRefIdx, newSearchRange );
1203      }
1204#endif
1205    }
1206  }
1207}
1208
1209/**
1210 Multi-loop slice encoding for different slice QP
1211
1212 \param pcPic    picture class
1213 */
1214void EncSlice::precompressSlice( Picture* pcPic )
1215{
1216  // if deltaQP RD is not used, simply return
1217  if ( m_pcCfg->getDeltaQpRD() == 0 )
1218  {
1219    return;
1220  }
1221
1222  if ( m_pcCfg->getUseRateCtrl() )
1223  {
1224    THROW("\nMultiple QP optimization is not allowed when rate control is enabled." );
1225  }
1226
1227  Slice* pcSlice        = pcPic->slices[getSliceSegmentIdx()];
1228
1229#if HEVC_DEPENDENT_SLICES
1230  if (pcSlice->getDependentSliceSegmentFlag())
1231  {
1232    // if this is a dependent slice segment, then it was optimised
1233    // when analysing the entire slice.
1234    return;
1235  }
1236#endif
1237
1238  if (pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES)
1239  {
1240    // TODO: investigate use of average cost per CTU so that this Slice Mode can be used.
1241    THROW( "Unable to optimise Slice-level QP if Slice Mode is set to FIXED_NUMBER_OF_BYTES\n" );
1242  }
1243
1244  double     dPicRdCostBest = MAX_DOUBLE;
1245  uint32_t       uiQpIdxBest = 0;
1246
1247  double dFrameLambda;
1248  int SHIFT_QP = 12
1249                 + 6
1250                     * (pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8
1251                        - DISTORTION_PRECISION_ADJUSTMENT(pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA)));
1252
1253  // set frame lambda
1254  if (m_pcCfg->getGOPSize() > 1)
1255  {
1256    dFrameLambda = 0.68 * pow (2, (m_viRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
1257  }
1258  else
1259  {
1260    dFrameLambda = 0.68 * pow (2, (m_viRdPicQp[0] - SHIFT_QP) / 3.0);
1261  }
1262
1263  // for each QP candidate
1264  for ( uint32_t uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
1265  {
1266    pcSlice       ->setSliceQp             ( m_viRdPicQp    [uiQpIdx] );
1267    setUpLambda(pcSlice, m_vdRdPicLambda[uiQpIdx], m_viRdPicQp    [uiQpIdx]);
1268
1269    // try compress
1270    compressSlice   ( pcPic, true, m_pcCfg->getFastDeltaQp());
1271
1272    uint64_t uiPicDist        = m_uiPicDist; // Distortion, as calculated by compressSlice.
1273    // NOTE: This distortion is the chroma-weighted SSE distortion for the slice.
1274    //       Previously a standard SSE distortion was calculated (for the entire frame).
1275    //       Which is correct?
1276#if W0038_DB_OPT
1277    // TODO: Update loop filter, SAO and distortion calculation to work on one slice only.
1278    // uiPicDist = m_pcGOPEncoder->preLoopFilterPicAndCalcDist( pcPic );
1279#endif
1280    // compute RD cost and choose the best
1281    double dPicRdCost = double( uiPicDist ) + dFrameLambda * double( m_uiPicTotalBits );
1282
1283    if ( dPicRdCost < dPicRdCostBest )
1284    {
1285      uiQpIdxBest    = uiQpIdx;
1286      dPicRdCostBest = dPicRdCost;
1287    }
1288  }
1289
1290  // set best values
1291  pcSlice       ->setSliceQp             ( m_viRdPicQp    [uiQpIdxBest] );
1292  setUpLambda(pcSlice, m_vdRdPicLambda[uiQpIdxBest], m_viRdPicQp    [uiQpIdxBest]);
1293}
1294
1295void EncSlice::calCostSliceI(Picture* pcPic) // TODO: this only analyses the first slice segment. What about the others?
1296{
1297  double         iSumHadSlice      = 0;
1298  Slice * const  pcSlice           = pcPic->slices[getSliceSegmentIdx()];
1299  const TileMap &tileMap           = *pcPic->tileMap;
1300  const PreCalcValues& pcv         = *pcPic->cs->pcv;
1301  const SPS     &sps               = *(pcSlice->getSPS());
1302  const int      shift             = sps.getBitDepth(CHANNEL_TYPE_LUMA)-8;
1303  const int      offset            = (shift>0)?(1<<(shift-1)):0;
1304
1305#if HEVC_DEPENDENT_SLICES
1306  pcSlice->setSliceSegmentBits(0);
1307#endif
1308
1309  uint32_t startCtuTsAddr, boundingCtuTsAddr;
1310  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic );
1311
1312  for( uint32_t ctuTsAddr = startCtuTsAddr, ctuRsAddr = tileMap.getCtuTsToRsAddrMap( startCtuTsAddr);
1313       ctuTsAddr < boundingCtuTsAddr;
1314       ctuRsAddr = tileMap.getCtuTsToRsAddrMap(++ctuTsAddr) )
1315  {
1316    Position pos( (ctuRsAddr % pcv.widthInCtus) * pcv.maxCUWidth, (ctuRsAddr / pcv.widthInCtus) * pcv.maxCUHeight);
1317
1318    const int height  = std::min( pcv.maxCUHeight, pcv.lumaHeight - pos.y );
1319    const int width   = std::min( pcv.maxCUWidth,  pcv.lumaWidth  - pos.x );
1320    const CompArea blk( COMPONENT_Y, pcv.chrFormat, pos, Size( width, height));
1321    int iSumHad = m_pcCuEncoder->updateCtuDataISlice( pcPic->getOrigBuf( blk ) );
1322
1323    (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra=(iSumHad+offset)>>shift;
1324    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra;
1325
1326  }
1327  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
1328}
1329
1330/** \param pcPic   picture class
1331 */
1332void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP )
1333{
1334  // if bCompressEntireSlice is true, then the entire slice (not slice segment) is compressed,
1335  //   effectively disabling the slice-segment-mode.
1336
1337  Slice* const pcSlice    = pcPic->slices[getSliceSegmentIdx()];
1338  uint32_t  startCtuTsAddr;
1339  uint32_t  boundingCtuTsAddr;
1340
1341#if HEVC_DEPENDENT_SLICES
1342  pcSlice->setSliceSegmentBits(0);
1343#endif
1344  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic );
1345  if (bCompressEntireSlice)
1346  {
1347    boundingCtuTsAddr = pcSlice->getSliceCurEndCtuTsAddr();
1348#if HEVC_DEPENDENT_SLICES
1349    pcSlice->setSliceSegmentCurEndCtuTsAddr(boundingCtuTsAddr);
1350#endif
1351  }
1352
1353  // initialize cost values - these are used by precompressSlice (they should be parameters).
1354  m_uiPicTotalBits  = 0;
1355  m_uiPicDist       = 0;
1356
1357  pcSlice->setSliceQpBase( pcSlice->getSliceQp() );
1358
1359  m_CABACEstimator->initCtxModels( *pcSlice );
1360
1361#if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
1362  for( int jId = 1; jId < m_pcLib->getNumCuEncStacks(); jId++ )
1363  {
1364    CABACWriter* cw = m_pcLib->getCABACEncoder( jId )->getCABACEstimator( pcSlice->getSPS() );
1365    cw->initCtxModels( *pcSlice );
1366  }
1367
1368#endif
1369  m_pcCuEncoder->getModeCtrl()->setFastDeltaQp(bFastDeltaQP);
1370
1371
1372  //------------------------------------------------------------------------------
1373  //  Weighted Prediction parameters estimation.
1374  //------------------------------------------------------------------------------
1375  // calculate AC/DC values for current picture
1376  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
1377  {
1378    xCalcACDCParamSlice(pcSlice);
1379  }
1380
1381  const bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
1382
1383  if ( bWp_explicit )
1384  {
1385    //------------------------------------------------------------------------------
1386    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
1387    //------------------------------------------------------------------------------
1388#if HEVC_DEPENDENT_SLICES
1389    if ( pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES || pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES )
1390#else
1391    if(pcSlice->getSliceMode() == FIXED_NUMBER_OF_BYTES)
1392#endif
1393    {
1394      EXIT("Weighted Prediction is not yet supported with slice mode determined by max number of bins.");
1395    }
1396
1397    xEstimateWPParamSlice( pcSlice, m_pcCfg->getWeightedPredictionMethod() );
1398    pcSlice->initWpScaling(pcSlice->getSPS());
1399
1400    // check WP on/off
1401    xCheckWPEnable( pcSlice );
1402  }
1403
1404
1405#if HEVC_DEPENDENT_SLICES
1406  // Adjust initial state if this is the start of a dependent slice.
1407  {
1408    const TileMap&  tileMap                 = *pcPic->tileMap;
1409    const uint32_t      ctuRsAddr               = tileMap.getCtuTsToRsAddrMap( startCtuTsAddr);
1410    const uint32_t      currentTileIdx          = tileMap.getTileIdxMap(ctuRsAddr);
1411    const Tile&     currentTile             = tileMap.tiles[currentTileIdx];
1412    const uint32_t      firstCtuRsAddrOfTile    = currentTile.getFirstCtuRsAddr();
1413    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
1414    {
1415      // This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used.
1416      if( currentTile.getTileWidthInCtus() >= 2 || !m_pcCfg->getEntropyCodingSyncEnabledFlag() )
1417      {
1418        m_CABACEstimator->getCtx() = m_lastSliceSegmentEndContextState;
1419        m_CABACEstimator->start();
1420      }
1421    }
1422  }
1423#endif
1424
1425#if HEVC_DEPENDENT_SLICES
1426  if( !pcSlice->getDependentSliceSegmentFlag() )
1427  {
1428#endif
1429    pcPic->m_prevQP[0] = pcPic->m_prevQP[1] = pcSlice->getSliceQp();
1430#if HEVC_DEPENDENT_SLICES
1431  }
1432#endif
1433
1434  CHECK( pcPic->m_prevQP[0] == std::numeric_limits<int>::max(), "Invalid previous QP" );
1435
1436  CodingStructure&  cs          = *pcPic->cs;
1437  cs.slice    = pcSlice;
1438  cs.pcv      = pcSlice->getPPS()->pcv;
1439  cs.fracBits = 0;
1440
1441  if( startCtuTsAddr == 0 && ( pcSlice->getPOC() != m_pcCfg->getSwitchPOC() || -1 == m_pcCfg->getDebugCTU() ) )
1442  {
1443    cs.initStructData (pcSlice->getSliceQp(), pcSlice->getPPS()->getTransquantBypassEnabledFlag());
1444  }
1445
1446#if ENABLE_QPA
1447  if (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && (boundingCtuTsAddr > startCtuTsAddr))
1448  {
1449    if (applyQPAdaptation (pcPic, pcSlice, *cs.pcv, startCtuTsAddr, boundingCtuTsAddr, m_pcCfg->getLumaLevelToDeltaQPMapping().mode == LUMALVL_TO_DQP_NUM_MODES,
1450                           (m_pcCfg->getBaseQP() >= 38) || (m_pcCfg->getSourceWidth() <= 512 && m_pcCfg->getSourceHeight() <= 320), m_adaptedLumaQP))
1451    {
1452      m_CABACEstimator->initCtxModels (*pcSlice);
1453#if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
1454      for (int jId = 1; jId < m_pcLib->getNumCuEncStacks(); jId++)
1455      {
1456        CABACWriter* cw = m_pcLib->getCABACEncoder (jId)->getCABACEstimator (pcSlice->getSPS());
1457        cw->initCtxModels (*pcSlice);
1458      }
1459#endif
1460#if HEVC_DEPENDENT_SLICES
1461      if (!pcSlice->getDependentSliceSegmentFlag())
1462      {
1463#endif
1464        pcPic->m_prevQP[0] = pcPic->m_prevQP[1] = pcSlice->getSliceQp();
1465#if HEVC_DEPENDENT_SLICES
1466      }
1467#endif
1468      if (startCtuTsAddr == 0)
1469      {
1470        cs.currQP[0] = cs.currQP[1] = pcSlice->getSliceQp(); // cf code above
1471      }
1472    }
1473  }
1474#endif // ENABLE_QPA
1475
1476#if ENABLE_WPP_PARALLELISM
1477  bool bUseThreads = m_pcCfg->getNumWppThreads() > 1;
1478  if( bUseThreads )
1479  {
1480    CHECK( startCtuTsAddr != 0 || boundingCtuTsAddr != pcPic->cs->pcv->sizeInCtus, "not intended" );
1481
1482    pcPic->cs->allocateVectorsAtPicLevel();
1483
1484    omp_set_num_threads( m_pcCfg->getNumWppThreads() + m_pcCfg->getNumWppExtraLines() );
1485
1486    #pragma omp parallel for schedule(static,1) if(bUseThreads)
1487    for( int ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ctuTsAddr += widthInCtus )
1488    {
1489      // wpp thread start
1490      pcPic->scheduler.setWppThreadId();
1491#if ENABLE_SPLIT_PARALLELISM
1492      pcPic->scheduler.setSplitThreadId( 0 );
1493#endif
1494      encodeCtus( pcPic, bCompressEntireSlice, bFastDeltaQP, ctuTsAddr, ctuTsAddr + widthInCtus, m_pcLib );
1495      // wpp thread stop
1496    }
1497  }
1498  else
1499#endif
1500#if K0149_BLOCK_STATISTICS
1501  const SPS *sps = pcSlice->getSPS();
1502  CHECK(sps == 0, "No SPS present");
1503  writeBlockStatisticsHeader(sps);
1504#endif
1505  m_pcInterSearch->resetAffineMVList();
1506  encodeCtus( pcPic, bCompressEntireSlice, bFastDeltaQP, startCtuTsAddr, boundingCtuTsAddr, m_pcLib );
1507
1508#if HEVC_DEPENDENT_SLICES
1509  // store context state at the end of this slice-segment, in case the next slice is a dependent slice and continues using the CABAC contexts.
1510  if( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() )
1511  {
1512    m_lastSliceSegmentEndContextState = m_CABACEstimator->getCtx();//ctx end of dep.slice
1513  }
1514#endif
1515
1516}
1517
1518void EncSlice::checkDisFracMmvd( Picture* pcPic, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr )
1519{
1520  CodingStructure&  cs            = *pcPic->cs;
1521  Slice* pcSlice                  = cs.slice;
1522  const PreCalcValues& pcv        = *cs.pcv;
1523  const uint32_t    widthInCtus   = pcv.widthInCtus;
1524  const TileMap&  tileMap         = *pcPic->tileMap;
1525  const uint32_t hashThreshold    = 20;
1526  uint32_t totalCtu               = 0;
1527  uint32_t hashRatio              = 0;
1528
1529  if ( !pcSlice->getSPS()->getFpelMmvdEnabledFlag() )
1530  {
1531    return;
1532  }
1533
1534  for ( uint32_t ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ctuTsAddr++ )
1535  {
1536    const uint32_t ctuRsAddr = tileMap.getCtuTsToRsAddrMap( ctuTsAddr );
1537    const uint32_t ctuXPosInCtus        = ctuRsAddr % widthInCtus;
1538    const uint32_t ctuYPosInCtus        = ctuRsAddr / widthInCtus;
1539
1540    const Position pos ( ctuXPosInCtus * pcv.maxCUWidth, ctuYPosInCtus * pcv.maxCUHeight );
1541    const UnitArea ctuArea( cs.area.chromaFormat, Area( pos.x, pos.y, pcv.maxCUWidth, pcv.maxCUHeight ) );
1542
1543    hashRatio += m_pcCuEncoder->getIbcHashMap().getHashHitRatio( ctuArea.Y() );
1544    totalCtu++;
1545  }
1546
1547  if ( hashRatio > totalCtu * hashThreshold )
1548  {
1549    pcSlice->setDisFracMMVD( true );
1550  }
1551  if (!pcSlice->getDisFracMMVD()) {
1552    bool useIntegerMVD = (pcPic->lwidth()*pcPic->lheight() > 1920 * 1080);
1553    pcSlice->setDisFracMMVD( useIntegerMVD );
1554  }
1555}
1556
1557void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr, EncLib* pEncLib )
1558{
1559  CodingStructure&  cs            = *pcPic->cs;
1560  Slice* pcSlice                  = cs.slice;
1561  const PreCalcValues& pcv        = *cs.pcv;
1562  const uint32_t        widthInCtus   = pcv.widthInCtus;
1563  const TileMap&  tileMap         = *pcPic->tileMap;
1564#if ENABLE_QPA
1565  const int iQPIndex              = pcSlice->getSliceQpBase();
1566#endif
1567
1568#if ENABLE_WPP_PARALLELISM
1569  const int       dataId          = pcPic->scheduler.getWppDataId();
1570#elif ENABLE_SPLIT_PARALLELISM
1571  const int       dataId          = 0;
1572#endif
1573  CABACWriter*    pCABACWriter    = pEncLib->getCABACEncoder( PARL_PARAM0( dataId ) )->getCABACEstimator( pcSlice->getSPS() );
1574  TrQuant*        pTrQuant        = pEncLib->getTrQuant( PARL_PARAM0( dataId ) );
1575  RdCost*         pRdCost         = pEncLib->getRdCost( PARL_PARAM0( dataId ) );
1576  EncCfg*         pCfg            = pEncLib;
1577  RateCtrl*       pRateCtrl       = pEncLib->getRateCtrl();
1578#if ENABLE_WPP_PARALLELISM
1579  // first version dont use ctx from above
1580  pCABACWriter->initCtxModels( *pcSlice );
1581#endif
1582#if RDOQ_CHROMA_LAMBDA
1583  pTrQuant    ->setLambdas( pcSlice->getLambdas() );
1584#else
1585  pTrQuant    ->setLambda ( pcSlice->getLambdas()[0] );
1586#endif
1587  pRdCost     ->setLambda ( pcSlice->getLambdas()[0], pcSlice->getSPS()->getBitDepths() );
1588
1589  int prevQP[2];
1590  int currQP[2];
1591  prevQP[0] = prevQP[1] = pcSlice->getSliceQp();
1592  currQP[0] = currQP[1] = pcSlice->getSliceQp();
1593
1594#if HEVC_DEPENDENT_SLICES
1595  if( !pcSlice->getDependentSliceSegmentFlag() )
1596  {
1597#endif
1598    prevQP[0] = prevQP[1] = pcSlice->getSliceQp();
1599#if HEVC_DEPENDENT_SLICES
1600  }
1601#endif
1602  if ( pcSlice->getSPS()->getFpelMmvdEnabledFlag() ||
1603      (pcSlice->getSPS()->getIBCFlag() && m_pcCuEncoder->getEncCfg()->getIBCHashSearch()))
1604  {
1605#if JVET_N0329_IBC_SEARCH_IMP
1606    m_pcCuEncoder->getIbcHashMap().rebuildPicHashMap(cs.picture->getTrueOrigBuf());
1607    if (m_pcCfg->getIntraPeriod() != -1)
1608    {
1609      int hashBlkHitPerc = m_pcCuEncoder->getIbcHashMap().calHashBlkMatchPerc(cs.area.Y());
1610      cs.slice->setDisableSATDForRD(hashBlkHitPerc > 59);
1611    }
1612#else
1613    if (pcSlice->getSPS()->getUseReshaper() && m_pcLib->getReshaper()->getCTUFlag() && pcSlice->getSPS()->getIBCFlag())
1614      cs.picture->getOrigBuf(COMPONENT_Y).rspSignal(m_pcLib->getReshaper()->getFwdLUT());
1615    m_pcCuEncoder->getIbcHashMap().rebuildPicHashMap( cs.picture->getOrigBuf() );
1616    if (pcSlice->getSPS()->getUseReshaper() && m_pcLib->getReshaper()->getCTUFlag() && pcSlice->getSPS()->getIBCFlag())
1617      cs.picture->getOrigBuf().copyFrom(cs.picture->getTrueOrigBuf());
1618#endif
1619  }
1620  checkDisFracMmvd( pcPic, startCtuTsAddr, boundingCtuTsAddr );
1621  // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
1622  for( uint32_t ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ctuTsAddr++ )
1623  {
1624    const int32_t ctuRsAddr = tileMap.getCtuTsToRsAddrMap( ctuTsAddr );
1625
1626    // update CABAC state
1627    const uint32_t firstCtuRsAddrOfTile = tileMap.tiles[tileMap.getTileIdxMap(ctuRsAddr)].getFirstCtuRsAddr();
1628    const uint32_t tileXPosInCtus       = firstCtuRsAddrOfTile % widthInCtus;
1629    const uint32_t ctuXPosInCtus        = ctuRsAddr % widthInCtus;
1630    const uint32_t ctuYPosInCtus        = ctuRsAddr / widthInCtus;
1631
1632    const Position pos (ctuXPosInCtus * pcv.maxCUWidth, ctuYPosInCtus * pcv.maxCUHeight);
1633    const UnitArea ctuArea( cs.area.chromaFormat, Area( pos.x, pos.y, pcv.maxCUWidth, pcv.maxCUHeight ) );
1634    DTRACE_UPDATE( g_trace_ctx, std::make_pair( "ctu", ctuRsAddr ) );
1635
1636    if( pCfg->getSwitchPOC() != pcPic->poc || -1 == pCfg->getDebugCTU() )
1637#if FIXBUG_RESET_LUT
1638    if ((cs.slice->getSliceType() != I_SLICE || cs.sps->getIBCFlag()) && ctuXPosInCtus == tileXPosInCtus)
1639#else
1640    if ((cs.slice->getSliceType() != I_SLICE || cs.sps->getIBCFlag()) && ctuXPosInCtus == 0)
1641#endif
1642    {
1643      cs.motionLut.lut.resize(0);
1644      cs.motionLut.lutIbc.resize(0);
1645#if !JVET_N0266_SMALL_BLOCKS
1646      cs.motionLut.lutShare.resize(0);
1647#endif
1648      cs.motionLut.lutShareIbc.resize(0);
1649    }
1650
1651#if ENABLE_WPP_PARALLELISM
1652    pcPic->scheduler.wait( ctuXPosInCtus, ctuYPosInCtus );
1653#endif
1654
1655    if (ctuRsAddr == firstCtuRsAddrOfTile)
1656    {
1657      pCABACWriter->initCtxModels( *pcSlice );
1658      prevQP[0] = prevQP[1] = pcSlice->getSliceQp();
1659    }
1660    else if (ctuXPosInCtus == tileXPosInCtus && pEncLib->getEntropyCodingSyncEnabledFlag())
1661    {
1662      // reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile).
1663      pCABACWriter->initCtxModels( *pcSlice );
1664      if( cs.getCURestricted( pos.offset(pcv.maxCUWidth, -1), pcSlice->getIndependentSliceIdx(), tileMap.getTileIdxMap( pos ), CH_L ) )
1665      {
1666        // Top-right is available, we use it.
1667        pCABACWriter->getCtx() = pEncLib->m_entropyCodingSyncContextState;
1668      }
1669      prevQP[0] = prevQP[1] = pcSlice->getSliceQp();
1670    }
1671
1672#if ENABLE_WPP_PARALLELISM
1673    if( ctuXPosInCtus == 0 && ctuYPosInCtus > 0 && widthInCtus > 1 && ( pEncLib->getNumWppThreads() > 1 || pEncLib->getEnsureWppBitEqual() ) )
1674    {
1675      pCABACWriter->getCtx() = pEncLib->m_entropyCodingSyncContextStateVec[ctuYPosInCtus-1];  // last line
1676    }
1677#else
1678#endif
1679
1680#if RDOQ_CHROMA_LAMBDA && ENABLE_QPA && !ENABLE_QPA_SUB_CTU
1681    double oldLambdaArray[MAX_NUM_COMPONENT] = {0.0};
1682#endif
1683    const double oldLambda = pRdCost->getLambda();
1684    if ( pCfg->getUseRateCtrl() )
1685    {
1686      int estQP        = pcSlice->getSliceQp();
1687      double estLambda = -1.0;
1688      double bpp       = -1.0;
1689
1690      if( ( pcPic->slices[0]->isIRAP() && pCfg->getForceIntraQP() ) || !pCfg->getLCULevelRC() )
1691      {
1692        estQP = pcSlice->getSliceQp();
1693      }
1694      else
1695      {
1696        bpp = pRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->isIRAP());
1697        if ( pcPic->slices[0]->isIRAP())
1698        {
1699          estLambda = pRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1700        }
1701        else
1702        {
1703          estLambda = pRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1704          estQP     = pRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1705        }
1706
1707        estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP );
1708
1709        pRdCost->setLambda(estLambda, pcSlice->getSPS()->getBitDepths());
1710
1711#if RDOQ_CHROMA_LAMBDA
1712        // set lambda for RDOQ
1713        const double chromaLambda = estLambda / pRdCost->getChromaWeight();
1714        const double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda };
1715        pTrQuant->setLambdas( lambdaArray );
1716#else
1717        pTrQuant->setLambda( estLambda );
1718#endif
1719      }
1720
1721      pRateCtrl->setRCQP( estQP );
1722    }
1723#if ENABLE_QPA
1724    else if (pCfg->getUsePerceptQPA() && pcSlice->getPPS()->getUseDQP())
1725    {
1726#if ENABLE_QPA_SUB_CTU
1727      const int adaptedQP    = applyQPAdaptationSubCtu (cs, ctuArea, ctuRsAddr, m_pcCfg->getLumaLevelToDeltaQPMapping().mode == LUMALVL_TO_DQP_NUM_MODES);
1728#else
1729      const int adaptedQP    = pcPic->m_iOffsetCtu[ctuRsAddr];
1730#endif
1731      const double newLambda = pcSlice->getLambdas()[0] * pow (2.0, double (adaptedQP - iQPIndex) / 3.0);
1732      pcPic->m_uEnerHpCtu[ctuRsAddr] = newLambda; // for ALF and SAO
1733#if !ENABLE_QPA_SUB_CTU
1734#if RDOQ_CHROMA_LAMBDA
1735      pTrQuant->getLambdas (oldLambdaArray); // save the old lambdas
1736      const double chromaLambda = newLambda / pRdCost->getChromaWeight();
1737      const double lambdaArray[MAX_NUM_COMPONENT] = {newLambda, chromaLambda, chromaLambda};
1738      pTrQuant->setLambdas (lambdaArray);
1739#else
1740      pTrQuant->setLambda (newLambda);
1741#endif
1742      pRdCost->setLambda (newLambda, pcSlice->getSPS()->getBitDepths());
1743#endif
1744      currQP[0] = currQP[1] = adaptedQP;
1745    }
1746#endif
1747
1748    bool updateGbiCodingOrder = cs.slice->getSliceType() == B_SLICE && ctuTsAddr == startCtuTsAddr;
1749    if( updateGbiCodingOrder )
1750    {
1751      resetGbiCodingOrder(false, cs);
1752      m_pcInterSearch->initWeightIdxBits();
1753    }
1754    if (pcSlice->getSPS()->getUseReshaper())
1755    {
1756      m_pcCuEncoder->setDecCuReshaperInEncCU(m_pcLib->getReshaper(), pcSlice->getSPS()->getChromaFormatIdc());
1757
1758#if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
1759      for (int jId = 1; jId < m_pcLib->getNumCuEncStacks(); jId++)
1760      {
1761        m_pcLib->getCuEncoder(jId)->setDecCuReshaperInEncCU(m_pcLib->getReshaper(jId), pcSlice->getSPS()->getChromaFormatIdc());
1762      }
1763#endif
1764    }
1765    if( !cs.slice->isIntra() && pCfg->getMCTSEncConstraint() )
1766    {
1767      pcPic->mctsInfo.init( &cs, ctuRsAddr );
1768    }
1769
1770  if (pCfg->getSwitchPOC() != pcPic->poc || ctuRsAddr >= pCfg->getDebugCTU())
1771#if ENABLE_WPP_PARALLELISM
1772    pEncLib->getCuEncoder( dataId )->compressCtu( cs, ctuArea, ctuRsAddr, prevQP, currQP );
1773#else
1774    m_pcCuEncoder->compressCtu( cs, ctuArea, ctuRsAddr, prevQP, currQP );
1775#endif
1776
1777#if K0149_BLOCK_STATISTICS
1778    getAndStoreBlockStatistics(cs, ctuArea);
1779#endif
1780
1781    pCABACWriter->resetBits();
1782    pCABACWriter->coding_tree_unit( cs, ctuArea, prevQP, ctuRsAddr, true );
1783    const int numberOfWrittenBits = int( pCABACWriter->getEstFracBits() >> SCALE_BITS );
1784
1785    // Calculate if this CTU puts us over slice bit size.
1786    // cannot terminate if current slice/slice-segment would be 0 Ctu in size,
1787    const uint32_t validEndOfSliceCtuTsAddr = ctuTsAddr + (ctuTsAddr == startCtuTsAddr ? 1 : 0);
1788    // Set slice end parameter
1789    if(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceBits()+numberOfWrittenBits > (pcSlice->getSliceArgument()<<3))
1790    {
1791#if HEVC_DEPENDENT_SLICES
1792      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
1793#endif
1794      pcSlice->setSliceCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
1795      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
1796    }
1797#if HEVC_DEPENDENT_SLICES
1798    else if((!bCompressEntireSlice) && pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+numberOfWrittenBits > (pcSlice->getSliceSegmentArgument()<<3))
1799    {
1800      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
1801      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
1802    }
1803#endif
1804    if (boundingCtuTsAddr <= ctuTsAddr)
1805    {
1806      break;
1807    }
1808
1809#if ENABLE_WPP_PARALLELISM || ENABLE_SPLIT_PARALLELISM
1810#pragma omp critical
1811#endif
1812    pcSlice->setSliceBits( ( uint32_t ) ( pcSlice->getSliceBits() + numberOfWrittenBits ) );
1813#if ENABLE_WPP_PARALLELISM || ENABLE_SPLIT_PARALLELISM
1814#pragma omp critical
1815#endif
1816#if HEVC_DEPENDENT_SLICES
1817    pcSlice->setSliceSegmentBits( pcSlice->getSliceSegmentBits() + numberOfWrittenBits );
1818#endif
1819
1820    // Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled.
1821    if( ctuXPosInCtus == tileXPosInCtus + 1 && pEncLib->getEntropyCodingSyncEnabledFlag() )
1822    {
1823      pEncLib->m_entropyCodingSyncContextState = pCABACWriter->getCtx();
1824    }
1825#if ENABLE_WPP_PARALLELISM
1826    if( ctuXPosInCtus == 1 && ( pEncLib->getNumWppThreads() > 1 || pEncLib->getEnsureWppBitEqual() ) )
1827    {
1828      pEncLib->m_entropyCodingSyncContextStateVec[ctuYPosInCtus] = pCABACWriter->getCtx();
1829    }
1830#endif
1831
1832#if !ENABLE_WPP_PARALLELISM
1833    int actualBits = int(cs.fracBits >> SCALE_BITS);
1834    actualBits    -= (int)m_uiPicTotalBits;
1835#endif
1836    if ( pCfg->getUseRateCtrl() )
1837    {
1838#if ENABLE_WPP_PARALLELISM
1839      int actualBits      = int( cs.fracBits >> SCALE_BITS );
1840      actualBits         -= (int)m_uiPicTotalBits;
1841#endif
1842      int actualQP        = g_RCInvalidQPValue;
1843      double actualLambda = pRdCost->getLambda();
1844      int numberOfEffectivePixels    = 0;
1845
1846      int numberOfSkipPixel = 0;
1847      for (auto &cu : cs.traverseCUs(ctuArea, CH_L))
1848      {
1849        numberOfSkipPixel += cu.skip*cu.lumaSize().area();
1850      }
1851
1852      for( auto &cu : cs.traverseCUs( ctuArea, CH_L ) )
1853      {
1854        if( !cu.skip || cu.rootCbf )
1855        {
1856          numberOfEffectivePixels += cu.lumaSize().area();
1857          break;
1858        }
1859      }
1860      double skipRatio = (double)numberOfSkipPixel / ctuArea.lumaSize().area();
1861      CodingUnit* cu = cs.getCU( ctuArea.lumaPos(), CH_L );
1862
1863      if ( numberOfEffectivePixels == 0 )
1864      {
1865        actualQP = g_RCInvalidQPValue;
1866      }
1867      else
1868      {
1869        actualQP = cu->qp;
1870      }
1871      pRdCost->setLambda(oldLambda, pcSlice->getSPS()->getBitDepths());
1872      pRateCtrl->getRCPic()->updateAfterCTU(pRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, skipRatio,
1873        pcSlice->isIRAP() ? 0 : pCfg->getLCULevelRC());
1874    }
1875#if ENABLE_QPA && !ENABLE_QPA_SUB_CTU
1876    else if (pCfg->getUsePerceptQPA() && pcSlice->getPPS()->getUseDQP())
1877    {
1878#if RDOQ_CHROMA_LAMBDA
1879      pTrQuant->setLambdas (oldLambdaArray);
1880#else
1881      pTrQuant->setLambda (oldLambda);
1882#endif
1883      pRdCost->setLambda (oldLambda, pcSlice->getSPS()->getBitDepths());
1884    }
1885#endif
1886
1887#if !ENABLE_WPP_PARALLELISM
1888    m_uiPicTotalBits += actualBits;
1889    m_uiPicDist       = cs.dist;
1890#endif
1891#if ENABLE_WPP_PARALLELISM
1892    pcPic->scheduler.setReady( ctuXPosInCtus, ctuYPosInCtus );
1893#endif
1894  }
1895
1896  // this is wpp exclusive section
1897
1898//  m_uiPicTotalBits += actualBits;
1899//  m_uiPicDist       = cs.dist;
1900
1901}
1902
1903void EncSlice::encodeSlice   ( Picture* pcPic, OutputBitstream* pcSubstreams, uint32_t &numBinsCoded )
1904{
1905
1906  Slice *const pcSlice               = pcPic->slices[getSliceSegmentIdx()];
1907  const TileMap& tileMap             = *pcPic->tileMap;
1908#if HEVC_DEPENDENT_SLICES
1909  const uint32_t startCtuTsAddr          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1910  const uint32_t boundingCtuTsAddr       = pcSlice->getSliceSegmentCurEndCtuTsAddr();
1911  const bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1912#else
1913  const uint32_t startCtuTsAddr          = pcSlice->getSliceCurStartCtuTsAddr();
1914  const uint32_t boundingCtuTsAddr       = pcSlice->getSliceCurEndCtuTsAddr();
1915#endif
1916  const bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
1917
1918
1919  // setup coding structure
1920  CodingStructure& cs = *pcPic->cs;
1921  cs.slice            = pcSlice;
1922  // initialise entropy coder for the slice
1923  m_CABACWriter->initCtxModels( *pcSlice );
1924
1925  DTRACE( g_trace_ctx, D_HEADER, "=========== POC: %d ===========\n", pcSlice->getPOC() );
1926
1927#if HEVC_DEPENDENT_SLICES
1928  if (depSliceSegmentsEnabled)
1929  {
1930    // modify initial contexts with previous slice segment if this is a dependent slice.
1931    const uint32_t ctuRsAddr            = tileMap.getCtuTsToRsAddrMap( startCtuTsAddr );
1932    const uint32_t currentTileIdx       = tileMap.getTileIdxMap(ctuRsAddr);
1933    const Tile& currentTile         = tileMap.tiles[currentTileIdx];
1934    const uint32_t firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
1935
1936    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
1937    {
1938      if( currentTile.getTileWidthInCtus() >= 2 || !wavefrontsEnabled )
1939      {
1940        m_CABACWriter->getCtx() = m_lastSliceSegmentEndContextState;
1941      }
1942    }
1943  }
1944
1945  if( !pcSlice->getDependentSliceSegmentFlag() )
1946  {
1947#endif
1948    pcPic->m_prevQP[0] = pcPic->m_prevQP[1] = pcSlice->getSliceQp();
1949#if HEVC_DEPENDENT_SLICES
1950  }
1951#endif
1952
1953  const PreCalcValues& pcv = *cs.pcv;
1954  const uint32_t widthInCtus   = pcv.widthInCtus;
1955
1956  // for every CTU in the slice segment...
1957
1958  for( uint32_t ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ctuTsAddr++ )
1959  {
1960    const uint32_t ctuRsAddr            = tileMap.getCtuTsToRsAddrMap(ctuTsAddr);
1961    const Tile& currentTile         = tileMap.tiles[tileMap.getTileIdxMap(ctuRsAddr)];
1962    const uint32_t firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
1963    const uint32_t tileXPosInCtus       = firstCtuRsAddrOfTile % widthInCtus;
1964    const uint32_t tileYPosInCtus       = firstCtuRsAddrOfTile / widthInCtus;
1965    const uint32_t ctuXPosInCtus        = ctuRsAddr % widthInCtus;
1966    const uint32_t ctuYPosInCtus        = ctuRsAddr / widthInCtus;
1967    const uint32_t uiSubStrm            = tileMap.getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice);
1968
1969    DTRACE_UPDATE( g_trace_ctx, std::make_pair( "ctu", ctuRsAddr ) );
1970
1971    const Position pos (ctuXPosInCtus * pcv.maxCUWidth, ctuYPosInCtus * pcv.maxCUHeight);
1972    const UnitArea ctuArea (cs.area.chromaFormat, Area(pos.x, pos.y, pcv.maxCUWidth, pcv.maxCUHeight));
1973    m_CABACWriter->initBitstream( &pcSubstreams[uiSubStrm] );
1974
1975    // set up CABAC contexts' state for this CTU
1976    if (ctuRsAddr == firstCtuRsAddrOfTile)
1977    {
1978      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1979      {
1980        m_CABACWriter->initCtxModels( *pcSlice );
1981      }
1982    }
1983    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
1984    {
1985      // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line.
1986      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1987      {
1988        m_CABACWriter->initCtxModels( *pcSlice );
1989      }
1990      if( cs.getCURestricted( pos.offset( pcv.maxCUWidth, -1 ), pcSlice->getIndependentSliceIdx(), tileMap.getTileIdxMap( pos ), CH_L ) )
1991      {
1992        // Top-right is available, so use it.
1993        m_CABACWriter->getCtx() = m_entropyCodingSyncContextState;
1994      }
1995    }
1996
1997    bool updateGbiCodingOrder = cs.slice->getSliceType() == B_SLICE && ctuTsAddr == startCtuTsAddr;
1998    if( updateGbiCodingOrder )
1999    {
2000      resetGbiCodingOrder(false, cs);
2001    }
2002
2003    m_CABACWriter->coding_tree_unit( cs, ctuArea, pcPic->m_prevQP, ctuRsAddr );
2004
2005    // store probabilities of second CTU in line into buffer
2006    if( ctuXPosInCtus == tileXPosInCtus + 1 && wavefrontsEnabled )
2007    {
2008      m_entropyCodingSyncContextState = m_CABACWriter->getCtx();
2009    }
2010
2011    // terminate the sub-stream, if required (end of slice-segment, end of tile, end of wavefront-CTU-row):
2012    if( ctuTsAddr + 1 == boundingCtuTsAddr ||
2013         (  ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus () &&
2014          ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled )
2015         )
2016       )
2017    {
2018      m_CABACWriter->end_of_slice();
2019
2020      // Byte-alignment in slice_data() when new tile
2021      pcSubstreams[uiSubStrm].writeByteAlignment();
2022
2023      // write sub-stream size
2024      if( ctuTsAddr + 1 != boundingCtuTsAddr )
2025      {
2026        pcSlice->addSubstreamSize( (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations() );
2027      }
2028    }
2029  } // CTU-loop
2030
2031#if HEVC_DEPENDENT_SLICES
2032  if( depSliceSegmentsEnabled )
2033  {
2034    m_lastSliceSegmentEndContextState = m_CABACWriter->getCtx();//ctx end of dep.slice
2035  }
2036#endif
2037
2038#if HEVC_DEPENDENT_SLICES
2039  if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
2040#else
2041  if(pcSlice->getPPS()->getCabacInitPresentFlag())
2042#endif
2043  {
2044    m_encCABACTableIdx = m_CABACWriter->getCtxInitId( *pcSlice );
2045  }
2046  else
2047  {
2048    m_encCABACTableIdx = pcSlice->getSliceType();
2049  }
2050  numBinsCoded = m_CABACWriter->getNumBins();
2051
2052}
2053
2054void EncSlice::calculateBoundingCtuTsAddrForSlice(uint32_t &startCtuTSAddrSlice, uint32_t &boundingCtuTSAddrSlice, bool &haveReachedTileBoundary,
2055                                                   Picture* pcPic, const int sliceMode, const int sliceArgument)
2056{
2057  Slice* pcSlice = pcPic->slices[getSliceSegmentIdx()];
2058  const TileMap& tileMap = *( pcPic->tileMap );
2059  const PPS &pps         = *( pcSlice->getPPS() );
2060  const uint32_t numberOfCtusInFrame = pcPic->cs->pcv->sizeInCtus;
2061  boundingCtuTSAddrSlice=0;
2062  haveReachedTileBoundary=false;
2063
2064  switch (sliceMode)
2065  {
2066    case FIXED_NUMBER_OF_CTU:
2067      {
2068        uint32_t ctuAddrIncrement    = sliceArgument;
2069        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
2070      }
2071      break;
2072    case FIXED_NUMBER_OF_BYTES:
2073      boundingCtuTSAddrSlice  = numberOfCtusInFrame; // This will be adjusted later if required.
2074      break;
2075    case FIXED_NUMBER_OF_TILES:
2076      {
2077        const uint32_t tileIdx        = tileMap.getTileIdxMap( tileMap.getCtuTsToRsAddrMap(startCtuTSAddrSlice) );
2078        const uint32_t tileTotalCount = (pps.getNumTileColumnsMinus1()+1) * (pps.getNumTileRowsMinus1()+1);
2079        uint32_t ctuAddrIncrement   = 0;
2080
2081        for(uint32_t tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++)
2082        {
2083          if((tileIdx + tileIdxIncrement) < tileTotalCount)
2084          {
2085            uint32_t tileWidthInCtus    = tileMap.tiles[tileIdx + tileIdxIncrement].getTileWidthInCtus();
2086            uint32_t tileHeightInCtus   = tileMap.tiles[tileIdx + tileIdxIncrement].getTileHeightInCtus();
2087            ctuAddrIncrement       += (tileWidthInCtus * tileHeightInCtus);
2088          }
2089        }
2090
2091        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
2092      }
2093      break;
2094    default:
2095      boundingCtuTSAddrSlice    = numberOfCtusInFrame;
2096      break;
2097  }
2098
2099  // Adjust for tiles and wavefronts.
2100  const bool wavefrontsAreEnabled = pps.getEntropyCodingSyncEnabledFlag();
2101
2102  if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) &&
2103      (pps.getNumTileRowsMinus1() > 0 || pps.getNumTileColumnsMinus1() > 0))
2104  {
2105    const uint32_t ctuRsAddr                   = tileMap.getCtuTsToRsAddrMap(startCtuTSAddrSlice);
2106    const uint32_t startTileIdx                = tileMap.getTileIdxMap(ctuRsAddr);
2107    const Tile& startingTile               = tileMap.tiles[startTileIdx];
2108    const uint32_t  tileStartTsAddr            = tileMap.getCtuRsToTsAddrMap(startingTile.getFirstCtuRsAddr());
2109    const uint32_t  tileStartWidth             = startingTile.getTileWidthInCtus();
2110    const uint32_t  tileStartHeight            = startingTile.getTileHeightInCtus();
2111    const uint32_t tileLastTsAddr_excl        = tileStartTsAddr + tileStartWidth*tileStartHeight;
2112    const uint32_t tileBoundingCtuTsAddrSlice = tileLastTsAddr_excl;
2113    const uint32_t ctuColumnOfStartingTile     = ((startCtuTSAddrSlice-tileStartTsAddr)%tileStartWidth);
2114    if (wavefrontsAreEnabled && ctuColumnOfStartingTile!=0)
2115    {
2116      // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
2117      const uint32_t numberOfCTUsToEndOfRow            = tileStartWidth - ctuColumnOfStartingTile;
2118      const uint32_t wavefrontTileBoundingCtuAddrSlice = startCtuTSAddrSlice + numberOfCTUsToEndOfRow;
2119      if (wavefrontTileBoundingCtuAddrSlice < boundingCtuTSAddrSlice)
2120      {
2121        boundingCtuTSAddrSlice = wavefrontTileBoundingCtuAddrSlice;
2122      }
2123    }
2124
2125    if (tileBoundingCtuTsAddrSlice < boundingCtuTSAddrSlice)
2126    {
2127      boundingCtuTSAddrSlice = tileBoundingCtuTsAddrSlice;
2128      haveReachedTileBoundary = true;
2129    }
2130  }
2131  else if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) && wavefrontsAreEnabled && ((startCtuTSAddrSlice % pcPic->cs->pcv->widthInCtus) != 0))
2132  {
2133    // Adjust for wavefronts (no tiles).
2134    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
2135    boundingCtuTSAddrSlice = std::min(boundingCtuTSAddrSlice, startCtuTSAddrSlice - (startCtuTSAddrSlice % pcPic->cs->pcv->widthInCtus) + (pcPic->cs->pcv->widthInCtus));
2136  }
2137}
2138
2139/** Determines the starting and bounding CTU address of current slice / dependent slice
2140 * \param [out] startCtuTsAddr
2141 * \param [out] boundingCtuTsAddr
2142 * \param [in]  pcPic
2143
2144 * Updates startCtuTsAddr, boundingCtuTsAddr with appropriate CTU address
2145 */
2146void EncSlice::xDetermineStartAndBoundingCtuTsAddr  ( uint32_t& startCtuTsAddr, uint32_t& boundingCtuTsAddr, Picture* pcPic )
2147{
2148  Slice* pcSlice                 = pcPic->slices[getSliceSegmentIdx()];
2149
2150  // Non-dependent slice
2151  uint32_t startCtuTsAddrSlice           = pcSlice->getSliceCurStartCtuTsAddr();
2152  bool haveReachedTileBoundarySlice  = false;
2153  uint32_t boundingCtuTsAddrSlice;
2154  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSlice, boundingCtuTsAddrSlice, haveReachedTileBoundarySlice, pcPic,
2155                                     m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument());
2156  pcSlice->setSliceCurEndCtuTsAddr(   boundingCtuTsAddrSlice );
2157  pcSlice->setSliceCurStartCtuTsAddr( startCtuTsAddrSlice    );
2158
2159#if HEVC_DEPENDENT_SLICES
2160  // Dependent slice
2161  uint32_t startCtuTsAddrSliceSegment          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
2162  bool haveReachedTileBoundarySliceSegment = false;
2163  uint32_t boundingCtuTsAddrSliceSegment;
2164  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSliceSegment, boundingCtuTsAddrSliceSegment, haveReachedTileBoundarySliceSegment, pcPic,
2165                                     m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument());
2166  if (boundingCtuTsAddrSliceSegment>boundingCtuTsAddrSlice)
2167  {
2168    boundingCtuTsAddrSliceSegment = boundingCtuTsAddrSlice;
2169  }
2170  pcSlice->setSliceSegmentCurEndCtuTsAddr( boundingCtuTsAddrSliceSegment );
2171  pcSlice->setSliceSegmentCurStartCtuTsAddr(startCtuTsAddrSliceSegment);
2172
2173  // Make a joint decision based on reconstruction and dependent slice bounds
2174  startCtuTsAddr    = std::max(startCtuTsAddrSlice, startCtuTsAddrSliceSegment);
2175  boundingCtuTsAddr = boundingCtuTsAddrSliceSegment;
2176#else
2177  startCtuTsAddr = startCtuTsAddrSlice;
2178  boundingCtuTsAddr = boundingCtuTsAddrSlice;
2179#endif
2180}
2181
2182double EncSlice::xGetQPValueAccordingToLambda ( double lambda )
2183{
2184  return 4.2005*log(lambda) + 13.7122;
2185}
2186
2187//! \}