source: 3DVCSoftware/branches/HTM-4.1-dev2-RWTH-Fix/source/Lib/TLibEncoder/TEncEntropy.cpp @ 1233

Last change on this file since 1233 was 177, checked in by rwth, 12 years ago
  • added RWTH_B0036 (SDC+DLT)
  • Property svn:eol-style set to native
File size: 61.2 KB
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-2012, 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     TEncEntropy.cpp
35    \brief    entropy encoder class
36*/
37
38#include "TEncEntropy.h"
39#include "TLibCommon/TypeDef.h"
40#include "TLibCommon/TComAdaptiveLoopFilter.h"
41#include "TLibCommon/TComSampleAdaptiveOffset.h"
42
43//! \ingroup TLibEncoder
44//! \{
45
46Void TEncEntropy::setEntropyCoder ( TEncEntropyIf* e, TComSlice* pcSlice )
47{
48  m_pcEntropyCoderIf = e;
49  m_pcEntropyCoderIf->setSlice ( pcSlice );
50}
51
52Void TEncEntropy::encodeSliceHeader ( TComSlice* pcSlice )
53{
54#if SAO_UNIT_INTERLEAVING
55  if (pcSlice->getSPS()->getUseSAO())
56  {
57    pcSlice->setSaoInterleavingFlag(pcSlice->getAPS()->getSaoInterleavingFlag());
58    pcSlice->setSaoEnabledFlag     (pcSlice->getAPS()->getSaoParam()->bSaoFlag[0]);
59    if (pcSlice->getAPS()->getSaoInterleavingFlag())
60    {
61      pcSlice->setSaoEnabledFlagCb   (pcSlice->getAPS()->getSaoParam()->bSaoFlag[1]);
62      pcSlice->setSaoEnabledFlagCr   (pcSlice->getAPS()->getSaoParam()->bSaoFlag[2]);
63    }
64    else
65    {
66      pcSlice->setSaoEnabledFlagCb   (0);
67      pcSlice->setSaoEnabledFlagCr   (0);
68    }
69  }
70#endif
71
72  m_pcEntropyCoderIf->codeSliceHeader( pcSlice );
73  return;
74}
75
76#if TILES_WPP_ENTRY_POINT_SIGNALLING
77Void  TEncEntropy::encodeTilesWPPEntryPoint( TComSlice* pSlice )
78{
79  m_pcEntropyCoderIf->codeTilesWPPEntryPoint( pSlice );
80}
81#else
82Void TEncEntropy::encodeSliceHeaderSubstreamTable( TComSlice* pcSlice )
83{
84  m_pcEntropyCoderIf->codeSliceHeaderSubstreamTable( pcSlice );
85}
86#endif
87
88Void TEncEntropy::encodeTerminatingBit      ( UInt uiIsLast )
89{
90  m_pcEntropyCoderIf->codeTerminatingBit( uiIsLast );
91 
92  return;
93}
94
95Void TEncEntropy::encodeSliceFinish()
96{
97  m_pcEntropyCoderIf->codeSliceFinish();
98}
99
100#if OL_FLUSH
101Void TEncEntropy::encodeFlush()
102{
103  m_pcEntropyCoderIf->codeFlush();
104}
105Void TEncEntropy::encodeStart()
106{
107  m_pcEntropyCoderIf->encodeStart();
108}
109#endif
110
111Void TEncEntropy::encodeSEI(const SEI& sei)
112{
113  m_pcEntropyCoderIf->codeSEI(sei);
114  return;
115}
116
117Void TEncEntropy::encodePPS( TComPPS* pcPPS )
118{
119  m_pcEntropyCoderIf->codePPS( pcPPS );
120  return;
121}
122
123#if VIDYO_VPS_INTEGRATION
124Void TEncEntropy::encodeVPS( TComVPS* pcVPS )
125{
126  m_pcEntropyCoderIf->codeVPS( pcVPS );
127  return;
128}
129#endif
130
131#if VIDYO_VPS_INTEGRATION
132Void  codeVPS                 ( TComVPS* pcVPS );
133#endif
134
135#if HHI_MPI
136Void TEncEntropy::encodeSPS( TComSPS* pcSPS, Bool bIsDepth )
137{
138  m_pcEntropyCoderIf->codeSPS( pcSPS, bIsDepth );
139  return;
140}
141#else
142Void TEncEntropy::encodeSPS( TComSPS* pcSPS )
143{
144  m_pcEntropyCoderIf->codeSPS( pcSPS );
145  return;
146}
147#endif
148
149Void TEncEntropy::encodeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
150{
151  if ( pcCU->getSlice()->isIntra() )
152  {
153    return;
154  }
155  if( bRD )
156  {
157    uiAbsPartIdx = 0;
158  }
159#if BURST_IPCM
160  if( !bRD )
161  {
162    if( pcCU->getLastCUSucIPCMFlag() && pcCU->getIPCMFlag(uiAbsPartIdx) )
163    {
164      return;
165    }
166  }
167#endif
168  m_pcEntropyCoderIf->codeSkipFlag( pcCU, uiAbsPartIdx );
169}
170
171#if LGE_ILLUCOMP_B0045
172Void TEncEntropy::encodeICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
173{
174  if (pcCU->isIntra(uiAbsPartIdx) || (pcCU->getSlice()->getViewId() == 0) || pcCU->getSlice()->getSPS()->isDepth())
175  {
176    return;
177  }
178
179  if(!pcCU->getSlice()->getApplyIC())
180    return;
181
182  if( bRD )
183  {
184    uiAbsPartIdx = 0;
185  }
186
187  if(pcCU->isICFlagRequired(uiAbsPartIdx))
188    m_pcEntropyCoderIf->codeICFlag( pcCU, uiAbsPartIdx );
189}
190#endif
191
192Void TEncEntropy::codeFiltCountBit(ALFParam* pAlfParam, Int64* ruiRate)
193{
194  resetEntropy();
195  resetBits();
196  codeFilt(pAlfParam);
197  *ruiRate = getNumberOfWrittenBits();
198  resetEntropy();
199  resetBits();
200}
201
202Void TEncEntropy::codeAuxCountBit(ALFParam* pAlfParam, Int64* ruiRate)
203{
204  resetEntropy();
205  resetBits();
206  codeAux(pAlfParam);
207  *ruiRate = getNumberOfWrittenBits();
208  resetEntropy();
209  resetBits();
210}
211
212Void TEncEntropy::codeAux(ALFParam* pAlfParam)
213{
214  //  m_pcEntropyCoderIf->codeAlfUvlc(pAlfParam->realfiltNo);
215
216#if !LCU_SYNTAX_ALF
217  m_pcEntropyCoderIf->codeAlfFlag(pAlfParam->alf_pcr_region_flag);
218#endif
219#if !ALF_SINGLE_FILTER_SHAPE
220  m_pcEntropyCoderIf->codeAlfUvlc(pAlfParam->filter_shape); 
221#endif
222  Int noFilters = min(pAlfParam->filters_per_group-1, 2);
223  m_pcEntropyCoderIf->codeAlfUvlc(noFilters);
224
225  if(noFilters == 1)
226  {
227    m_pcEntropyCoderIf->codeAlfUvlc(pAlfParam->startSecondFilter);
228  }
229  else if (noFilters == 2)
230  {
231#if LCU_SYNTAX_ALF
232#if ALF_16_BA_GROUPS
233    Int numMergeFlags = 16;
234#else
235    Int numMergeFlags = 15;
236#endif
237#else
238#if ALF_16_BA_GROUPS
239    Int numMergeFlags = 16;
240#else
241    Int numMergeFlags = pAlfParam->alf_pcr_region_flag ? 16 : 15;
242#endif
243#endif
244    for (Int i=1; i<numMergeFlags; i++) 
245    {
246      m_pcEntropyCoderIf->codeAlfFlag (pAlfParam->filterPattern[i]);
247    }
248  }
249}
250
251Int TEncEntropy::lengthGolomb(int coeffVal, int k)
252{
253  int m = 2 << (k - 1);
254  int q = coeffVal / m;
255  if(coeffVal != 0)
256  {
257    return(q + 2 + k);
258  }
259  else
260  {
261    return(q + 1 + k);
262  }
263}
264
265Int TEncEntropy::codeFilterCoeff(ALFParam* ALFp)
266{
267  Int filters_per_group = ALFp->filters_per_group;
268  int sqrFiltLength = ALFp->num_coeff;
269  int i, k, kMin, kStart, minBits, ind, scanPos, maxScanVal, coeffVal, len = 0,
270    *pDepthInt=NULL, kMinTab[MAX_SCAN_VAL], bitsCoeffScan[MAX_SCAN_VAL][MAX_EXP_GOLOMB],
271    minKStart, minBitsKStart, bitsKStart;
272 
273  pDepthInt = pDepthIntTabShapes[ALFp->filter_shape];
274  maxScanVal = 0;
275#if ALF_SINGLE_FILTER_SHAPE
276  int minScanVal = MIN_SCAN_POS_CROSS;
277#else
278  int minScanVal = ( ALFp->filter_shape==ALF_STAR5x5 ) ? 0 : MIN_SCAN_POS_CROSS;
279#endif
280
281  for(i = 0; i < sqrFiltLength; i++)
282  {
283    maxScanVal = max(maxScanVal, pDepthInt[i]);
284  }
285 
286  // vlc for all
287  memset(bitsCoeffScan, 0, MAX_SCAN_VAL * MAX_EXP_GOLOMB * sizeof(int));
288  for(ind=0; ind<filters_per_group; ++ind)
289  {
290    for(i = 0; i < sqrFiltLength; i++)
291    {
292      scanPos=pDepthInt[i]-1;
293      coeffVal=abs(ALFp->coeffmulti[ind][i]);
294      for (k=1; k<15; k++)
295      {
296        bitsCoeffScan[scanPos][k]+=lengthGolomb(coeffVal, k);
297      }
298    }
299  }
300 
301  minBitsKStart = 0;
302  minKStart = -1;
303  for(k = 1; k < 8; k++)
304  { 
305    bitsKStart = 0; 
306    kStart = k;
307    for(scanPos = minScanVal; scanPos < maxScanVal; scanPos++)
308    {
309      kMin = kStart; 
310      minBits = bitsCoeffScan[scanPos][kMin];
311     
312      if(bitsCoeffScan[scanPos][kStart+1] < minBits)
313      {
314        kMin = kStart + 1; 
315        minBits = bitsCoeffScan[scanPos][kMin];
316      }
317      kStart = kMin;
318      bitsKStart += minBits;
319    }
320    if((bitsKStart < minBitsKStart) || (k == 1))
321    {
322      minBitsKStart = bitsKStart;
323      minKStart = k;
324    }
325  }
326 
327  kStart = minKStart; 
328  for(scanPos = minScanVal; scanPos < maxScanVal; scanPos++)
329  {
330    kMin = kStart; 
331    minBits = bitsCoeffScan[scanPos][kMin];
332   
333    if(bitsCoeffScan[scanPos][kStart+1] < minBits)
334    {
335      kMin = kStart + 1; 
336      minBits = bitsCoeffScan[scanPos][kMin];
337    }
338   
339    kMinTab[scanPos] = kMin;
340    kStart = kMin;
341  }
342 
343  // Coding parameters
344  ALFp->minKStart = minKStart;
345#if !LCU_SYNTAX_ALF 
346  ALFp->maxScanVal = maxScanVal;
347#endif
348  for(scanPos = minScanVal; scanPos < maxScanVal; scanPos++)
349  {
350    ALFp->kMinTab[scanPos] = kMinTab[scanPos];
351  }
352
353#if LCU_SYNTAX_ALF
354  if (ALFp->filters_per_group == 1)
355  {
356    len += writeFilterCoeffs(sqrFiltLength, filters_per_group, pDepthInt, ALFp->coeffmulti, kTableTabShapes[ALF_CROSS9x7_SQUARE3x3]);
357  }
358  else
359  {
360#endif
361  len += writeFilterCodingParams(minKStart, minScanVal, maxScanVal, kMinTab);
362
363  // Filter coefficients
364  len += writeFilterCoeffs(sqrFiltLength, filters_per_group, pDepthInt, ALFp->coeffmulti, kMinTab);
365#if LCU_SYNTAX_ALF
366  }
367#endif
368 
369  return len;
370}
371
372Int TEncEntropy::writeFilterCodingParams(int minKStart, int minScanVal, int maxScanVal, int kMinTab[])
373{
374  int scanPos;
375  int golombIndexBit;
376  int kMin;
377
378  // Golomb parameters
379  m_pcEntropyCoderIf->codeAlfUvlc(minKStart - 1);
380 
381  kMin = minKStart; 
382  for(scanPos = minScanVal; scanPos < maxScanVal; scanPos++)
383  {
384    golombIndexBit = (kMinTab[scanPos] != kMin)? 1: 0;
385   
386    assert(kMinTab[scanPos] <= kMin + 1);
387   
388    m_pcEntropyCoderIf->codeAlfFlag(golombIndexBit);
389    kMin = kMinTab[scanPos];
390  }   
391 
392  return 0;
393}
394
395Int TEncEntropy::writeFilterCoeffs(int sqrFiltLength, int filters_per_group, int pDepthInt[], 
396                                   int **FilterCoeff, int kMinTab[])
397{
398  int ind, scanPos, i;
399 
400  for(ind = 0; ind < filters_per_group; ++ind)
401  {
402    for(i = 0; i < sqrFiltLength; i++)
403    {
404      scanPos = pDepthInt[i] - 1;
405#if LCU_SYNTAX_ALF
406      Int k = (filters_per_group == 1) ? kMinTab[i] : kMinTab[scanPos];
407      golombEncode(FilterCoeff[ind][i], k);
408#else
409      golombEncode(FilterCoeff[ind][i], kMinTab[scanPos]);
410#endif
411    }
412  }
413  return 0;
414}
415
416Int TEncEntropy::golombEncode(int coeff, int k)
417{
418  int q, i;
419  int symbol = abs(coeff);
420 
421  q = symbol >> k;
422 
423  for (i = 0; i < q; i++)
424  {
425    m_pcEntropyCoderIf->codeAlfFlag(1);
426  }
427  m_pcEntropyCoderIf->codeAlfFlag(0);
428  // write one zero
429 
430  for(i = 0; i < k; i++)
431  {
432    m_pcEntropyCoderIf->codeAlfFlag(symbol & 0x01);
433    symbol >>= 1;
434  }
435 
436  if(coeff != 0)
437  {
438    int sign = (coeff > 0)? 1: 0;
439    m_pcEntropyCoderIf->codeAlfFlag(sign);
440  }
441  return 0;
442}
443
444Void TEncEntropy::codeFilt(ALFParam* pAlfParam)
445{
446  if(pAlfParam->filters_per_group > 1)
447  {
448    m_pcEntropyCoderIf->codeAlfFlag (pAlfParam->predMethod);
449  }
450  for(Int ind = 0; ind < pAlfParam->filters_per_group; ++ind)
451  {
452    m_pcEntropyCoderIf->codeAlfFlag (pAlfParam->nbSPred[ind]);
453  }
454  codeFilterCoeff (pAlfParam);
455}
456
457/** encode merge flag
458 * \param pcCU
459 * \param uiAbsPartIdx
460 * \param uiPUIdx
461 * \returns Void
462 */
463Void TEncEntropy::encodeMergeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiPUIdx )
464{ 
465  // at least one merge candidate exists
466  m_pcEntropyCoderIf->codeMergeFlag( pcCU, uiAbsPartIdx );
467}
468
469/** encode merge index
470 * \param pcCU
471 * \param uiAbsPartIdx
472 * \param uiPUIdx
473 * \param bRD
474 * \returns Void
475 */
476Void TEncEntropy::encodeMergeIndex( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiPUIdx, Bool bRD )
477{
478  if( bRD )
479  {
480    uiAbsPartIdx = 0;
481    assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
482  }
483
484  UInt uiNumCand = MRG_MAX_NUM_CANDS;
485  if ( uiNumCand > 1 )
486  {
487    m_pcEntropyCoderIf->codeMergeIndex( pcCU, uiAbsPartIdx );
488  }
489}
490
491#if HHI_INTER_VIEW_RESIDUAL_PRED
492Void
493TEncEntropy::encodeResPredFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiPUIdx, Bool bRD )
494{
495  if( bRD )
496  {
497    uiAbsPartIdx = 0;
498  }
499
500  // check whether flag is coded
501  ROTVS( pcCU->getSlice()->getSPS()->isDepth                () );
502  ROFVS( pcCU->getSlice()->getSPS()->getViewId              () );
503  ROFVS( pcCU->getSlice()->getSPS()->getMultiviewResPredMode() );
504  ROTVS( pcCU->isIntra           ( uiAbsPartIdx )              );
505  ROFVS( pcCU->getResPredAvail   ( uiAbsPartIdx )              );
506#if LG_RESTRICTEDRESPRED_M24766
507  Int iPUResiPredShift[4];
508  pcCU->getPUResiPredShift(iPUResiPredShift, uiAbsPartIdx);
509  if(iPUResiPredShift[0] >= 0 || iPUResiPredShift[1] >= 0  || iPUResiPredShift[2] >= 0  || iPUResiPredShift[3] >= 0 )
510#endif
511  // encode flag
512  m_pcEntropyCoderIf->codeResPredFlag( pcCU, uiAbsPartIdx );
513}
514#endif
515
516#if LCU_SYNTAX_ALF
517/** parse the fixed length code (smaller than one max value) in ALF
518 * \param run: coded value
519 * \param rx: cur addr
520 * \param numLCUInWidth: # of LCU in one LCU
521 * \returns Void
522 */
523Void TEncEntropy::encodeAlfFixedLengthRun(UInt run, UInt rx, UInt numLCUInWidth)
524{
525  assert(numLCUInWidth > rx);
526  UInt maxValue = numLCUInWidth - rx - 1;
527  m_pcEntropyCoderIf->codeAlfFixedLengthIdx(run, maxValue);
528}
529
530/** parse the fixed length code (smaller than one max value) in ALF
531 * \param idx: coded value
532 * \param numFilterSetsInBuffer: max value
533 * \returns Void
534 */
535Void TEncEntropy::encodeAlfStoredFilterSetIdx(UInt idx, UInt numFilterSetsInBuffer)
536{
537  assert(numFilterSetsInBuffer > 0);
538  UInt maxValue = numFilterSetsInBuffer - 1;
539  m_pcEntropyCoderIf->codeAlfFixedLengthIdx(idx, maxValue);
540}
541
542Void TEncEntropy::encodeAlfParam(AlfParamSet* pAlfParamSet, Bool bSentInAPS, Int firstLCUAddr, Bool alfAcrossSlice)
543{
544  Bool isEnabled[NUM_ALF_COMPONENT];
545  Bool isUniParam[NUM_ALF_COMPONENT];
546
547  isEnabled[ALF_Y] = true;
548  isEnabled[ALF_Cb]= pAlfParamSet->isEnabled[ALF_Cb];
549  isEnabled[ALF_Cr]= pAlfParamSet->isEnabled[ALF_Cr];
550
551  isUniParam[ALF_Y]= pAlfParamSet->isUniParam[ALF_Y];
552  isUniParam[ALF_Cb]= pAlfParamSet->isUniParam[ALF_Cb];
553  isUniParam[ALF_Cr]= pAlfParamSet->isUniParam[ALF_Cr]; 
554
555
556  //alf_cb_enable_flag
557  m_pcEntropyCoderIf->codeAlfFlag(isEnabled[ALF_Cb]?1:0);
558  //alf_cr_enable_flag
559  m_pcEntropyCoderIf->codeAlfFlag(isEnabled[ALF_Cr]?1:0); 
560
561  for(Int compIdx = 0; compIdx< NUM_ALF_COMPONENT; compIdx++)
562  {
563    if(isEnabled[compIdx])
564    {
565      //alf_one_{luma, cb, cr}_unit_per_slice_flag
566      m_pcEntropyCoderIf->codeAlfFlag(isUniParam[compIdx]?1:0);
567    }
568  }
569  if(bSentInAPS)
570  {
571    //alf_num_lcu_in_width_minus1
572    m_pcEntropyCoderIf->codeAlfUvlc(pAlfParamSet->numLCUInWidth-1);
573    //alf_num_lcu_in_height_minus1
574    m_pcEntropyCoderIf->codeAlfUvlc(pAlfParamSet->numLCUInHeight-1);
575  }
576  else //sent in slice header
577  {
578    //alf_num_lcu_in_slice_minus1
579    m_pcEntropyCoderIf->codeAlfUvlc(pAlfParamSet->numLCU-1);
580  }
581
582
583  encodeAlfParamSet(pAlfParamSet, pAlfParamSet->numLCUInWidth, pAlfParamSet->numLCU, firstLCUAddr, alfAcrossSlice, 0, (Int)NUM_ALF_COMPONENT-1);
584
585}
586
587Bool TEncEntropy::getAlfRepeatRowFlag(Int compIdx, AlfParamSet* pAlfParamSet
588                                    , Int lcuIdxInSlice, Int lcuPos
589                                    , Int startlcuPosX, Int endlcuPosX
590                                    , Int numLCUInWidth
591                                    )
592{
593  assert(startlcuPosX == 0); //only the beginning of one LCU row needs to send repeat_row_flag
594 
595  Int len = endlcuPosX - startlcuPosX +1;
596  Bool isRepeatRow = true;
597  Int curPos;
598
599  for(Int i= 0; i < len; i++)
600  {
601    curPos = lcuIdxInSlice +i;
602    AlfUnitParam& alfUnitParam = pAlfParamSet->alfUnitParam[compIdx][curPos];
603    AlfUnitParam& alfUpUnitParam = pAlfParamSet->alfUnitParam[compIdx][curPos-numLCUInWidth];
604
605    if ( !(alfUnitParam == alfUpUnitParam) )
606    {
607      isRepeatRow = false;
608      break;
609    }
610  }
611
612  return isRepeatRow;
613}
614
615
616Int TEncEntropy::getAlfRun(Int compIdx, AlfParamSet* pAlfParamSet
617                          , Int lcuIdxInSlice, Int lcuPos
618                          , Int startlcuPosX, Int endlcuPosX
619                          )
620{
621  Int alfRun = 0;
622  Int len = endlcuPosX - startlcuPosX +1;
623  AlfUnitParam& alfLeftUnitParam = pAlfParamSet->alfUnitParam[compIdx][lcuIdxInSlice];
624
625
626
627  for(Int i= 1; i < len; i++)
628  {
629    AlfUnitParam& alfUnitParam = pAlfParamSet->alfUnitParam[compIdx][lcuIdxInSlice+ i];
630
631    if (alfUnitParam == alfLeftUnitParam)
632    {
633      alfRun++;
634    }
635    else
636    {
637      break;
638    }
639  }
640
641  return alfRun;
642
643}
644
645
646
647Void TEncEntropy::encodeAlfParamSet(AlfParamSet* pAlfParamSet, Int numLCUInWidth, Int numLCU, Int firstLCUAddr, Bool alfAcrossSlice, Int startCompIdx, Int endCompIdx)
648{
649  Int endLCUY       = (numLCU -1 + firstLCUAddr)/numLCUInWidth;
650  Int endLCUX       = (numLCU -1 + firstLCUAddr)%numLCUInWidth;
651
652  static Bool isRepeatedRow   [NUM_ALF_COMPONENT];
653  static Int  numStoredFilters[NUM_ALF_COMPONENT];
654  static Int* run             [NUM_ALF_COMPONENT];
655
656  for(Int compIdx =startCompIdx; compIdx <= endCompIdx; compIdx++)
657  {
658    isRepeatedRow[compIdx]    = false;
659    numStoredFilters[compIdx] = 0;
660
661    run[compIdx] = new Int[numLCU+1];
662    run[compIdx][0] = -1; 
663  }
664
665  Int  ry, rx, addrUp, endrX, lcuPos;
666
667  for(Int i=0; i< numLCU; i++)
668  {
669    lcuPos= firstLCUAddr+ i;
670    rx    = lcuPos% numLCUInWidth;
671    ry    = lcuPos/ numLCUInWidth;
672    endrX = ( ry == endLCUY)?( endLCUX ):(numLCUInWidth-1);
673
674    for(Int compIdx =startCompIdx; compIdx <= endCompIdx; compIdx++)
675    {
676      AlfUnitParam& alfUnitParam = pAlfParamSet->alfUnitParam[compIdx][i];
677      if(pAlfParamSet->isEnabled[compIdx])
678      {
679        if(!pAlfParamSet->isUniParam[compIdx])
680        {
681          addrUp = i-numLCUInWidth;
682          if(rx ==0 && addrUp >=0)
683          {
684            isRepeatedRow[compIdx] = getAlfRepeatRowFlag(compIdx, pAlfParamSet, i, lcuPos, rx, endrX, numLCUInWidth);
685
686            //alf_repeat_row_flag
687            m_pcEntropyCoderIf->codeAlfFlag(isRepeatedRow[compIdx]?1:0);
688          }
689
690          if(isRepeatedRow[compIdx])
691          {
692            assert(addrUp >=0);
693            run[compIdx][i] = run[compIdx][addrUp];
694          }
695          else
696          {
697            if(rx == 0 || run[compIdx][i] < 0)
698            {             
699              run[compIdx][i] = getAlfRun(compIdx, pAlfParamSet, i, lcuPos, rx, endrX);
700
701              if(addrUp < 0)
702              {
703                //alf_run_diff u(v)
704                encodeAlfFixedLengthRun(run[compIdx][i], rx, numLCUInWidth);               
705              }
706              else
707              {
708                //alf_run_diff s(v)
709                m_pcEntropyCoderIf->codeAlfSvlc(run[compIdx][i]- run[compIdx][addrUp]);
710
711              }
712
713              if(ry > 0 && (addrUp >=0 || alfAcrossSlice))
714              {
715                //alf_merge_up_flag
716                m_pcEntropyCoderIf->codeAlfFlag(  (alfUnitParam.mergeType == ALF_MERGE_UP)?1:0   ); 
717              }
718
719              if(alfUnitParam.mergeType != ALF_MERGE_UP)
720              {
721                assert(alfUnitParam.mergeType == ALF_MERGE_DISABLED);
722
723                //alf_lcu_enable_flag
724                m_pcEntropyCoderIf->codeAlfFlag(alfUnitParam.isEnabled ? 1 : 0);
725
726                if(alfUnitParam.isEnabled)
727                {
728                  if(numStoredFilters[compIdx] > 0)
729                  {
730                    //alf_new_filter_set_flag
731                    m_pcEntropyCoderIf->codeAlfFlag(alfUnitParam.isNewFilt ? 1:0);
732
733                    if(!alfUnitParam.isNewFilt)
734                    {
735                      //alf_stored_filter_set_idx
736                      encodeAlfStoredFilterSetIdx(alfUnitParam.storedFiltIdx, numStoredFilters[compIdx]);
737
738                    }
739                  }
740                  else
741                  {
742                    assert(alfUnitParam.isNewFilt);
743                  }
744
745                  if(alfUnitParam.isNewFilt)
746                  {
747                    assert(alfUnitParam.alfFiltParam->alf_flag == 1);
748                    encodeAlfParam(alfUnitParam.alfFiltParam);
749                    numStoredFilters[compIdx]++;
750                  }
751                }
752
753              }
754            }
755
756            run[compIdx][i+1] = run[compIdx][i] -1;
757          }
758
759        }
760        else // uni-param
761        {
762          if(i == 0)
763          {
764            //alf_lcu_enable_flag
765            m_pcEntropyCoderIf->codeAlfFlag(alfUnitParam.isEnabled?1:0);
766            if(alfUnitParam.isEnabled)
767            {
768              encodeAlfParam(alfUnitParam.alfFiltParam);
769            }
770          }
771        }
772      } // component enabled/disable
773    } //comp
774
775  }
776
777  for(Int compIdx =startCompIdx; compIdx <= endCompIdx; compIdx++)
778  {
779    delete[] run[compIdx];
780  }
781
782}
783#endif
784
785
786Void TEncEntropy::encodeAlfParam(ALFParam* pAlfParam)
787{
788#if LCU_SYNTAX_ALF
789  const Int numCoeff = (Int)ALF_MAX_NUM_COEF;
790
791  switch(pAlfParam->componentID)
792  {
793  case ALF_Cb:
794  case ALF_Cr:
795    {
796      for(Int pos=0; pos< numCoeff; pos++)
797      {
798        m_pcEntropyCoderIf->codeAlfSvlc(  pAlfParam->coeffmulti[0][pos]);
799
800      }
801    }
802    break;
803  case ALF_Y:
804    {
805      codeAux(pAlfParam);
806      codeFilt(pAlfParam);
807    }
808    break;
809  default:
810    {
811      printf("Not a legal component ID\n");
812      assert(0);
813      exit(-1);
814    }
815  }
816#else
817  if (!pAlfParam->alf_flag)
818  {
819    return;
820  }
821  Int pos;
822  codeAux(pAlfParam);
823  codeFilt(pAlfParam);
824 
825  // filter parameters for chroma
826  m_pcEntropyCoderIf->codeAlfUvlc(pAlfParam->chroma_idc);
827  if(pAlfParam->chroma_idc)
828  {
829#if !ALF_SINGLE_FILTER_SHAPE
830    m_pcEntropyCoderIf->codeAlfUvlc(pAlfParam->filter_shape_chroma);
831#endif
832    // filter coefficients for chroma
833    for(pos=0; pos<pAlfParam->num_coeff_chroma; pos++)
834    {
835      m_pcEntropyCoderIf->codeAlfSvlc(pAlfParam->coeff_chroma[pos]);
836    }
837  }
838#endif
839}
840
841Void TEncEntropy::encodeAlfCtrlFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
842{
843  if( bRD )
844  {
845    uiAbsPartIdx = 0;
846  }
847  m_pcEntropyCoderIf->codeAlfCtrlFlag( pcCU, uiAbsPartIdx );
848}
849
850
851/** Encode ALF CU control flag
852 * \param uiFlag ALF CU control flag: 0 or 1
853 */
854Void TEncEntropy::encodeAlfCtrlFlag(UInt uiFlag)
855{
856  assert(uiFlag == 0 || uiFlag == 1);
857  m_pcEntropyCoderIf->codeAlfCtrlFlag( uiFlag );
858}
859
860
861/** Encode ALF CU control flag parameters
862 * \param pAlfParam ALF parameters
863 */
864Void TEncEntropy::encodeAlfCtrlParam(AlfCUCtrlInfo& cAlfParam, Int iNumCUsInPic)
865{
866  // region control parameters for luma
867  m_pcEntropyCoderIf->codeAlfFlag(cAlfParam.cu_control_flag);
868
869  if (cAlfParam.cu_control_flag == 0)
870  { 
871    return;
872  }
873
874  m_pcEntropyCoderIf->codeAlfCtrlDepth();
875
876  Int iSymbol    = ((Int)cAlfParam.num_alf_cu_flag - iNumCUsInPic);
877  m_pcEntropyCoderIf->codeAlfSvlc(iSymbol);
878
879  for(UInt i=0; i< cAlfParam.num_alf_cu_flag; i++)
880  {
881    m_pcEntropyCoderIf->codeAlfCtrlFlag( cAlfParam.alf_cu_flag[i] );
882  }
883}
884
885/** encode prediction mode
886 * \param pcCU
887 * \param uiAbsPartIdx
888 * \param bRD
889 * \returns Void
890 */
891Void TEncEntropy::encodePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
892{
893  if( bRD )
894  {
895    uiAbsPartIdx = 0;
896  }
897#if BURST_IPCM
898  if( !bRD )
899  {
900    if( pcCU->getLastCUSucIPCMFlag() && pcCU->getIPCMFlag(uiAbsPartIdx) )
901    {
902      return;
903    }
904  }
905#endif
906
907#if !RWTH_SDC_DLT_B0036
908  if ( pcCU->getSlice()->isIntra() )
909  {
910    return;
911  }
912#endif
913
914  m_pcEntropyCoderIf->codePredMode( pcCU, uiAbsPartIdx );
915 
916#if RWTH_SDC_DLT_B0036
917  // if B-Slice, code SDC flag later
918  if( !pcCU->getSlice()->isInterB() && pcCU->getSlice()->getSPS()->isDepth() && pcCU->isIntra(uiAbsPartIdx) )
919  {
920    // encode SDC flag
921    encodeSDCFlag(pcCU, uiAbsPartIdx, bRD);
922  }
923#endif
924}
925
926// Split mode
927Void TEncEntropy::encodeSplitFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
928{
929  if( bRD )
930  {
931    uiAbsPartIdx = 0;
932  }
933#if BURST_IPCM
934  if( !bRD )
935  {
936    if( pcCU->getLastCUSucIPCMFlag() && pcCU->getIPCMFlag(uiAbsPartIdx) )
937    {
938      return;
939    }
940  }
941#endif
942
943  m_pcEntropyCoderIf->codeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
944}
945
946/** encode partition size
947 * \param pcCU
948 * \param uiAbsPartIdx
949 * \param uiDepth
950 * \param bRD
951 * \returns Void
952 */
953Void TEncEntropy::encodePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
954{
955  if( bRD )
956  {
957    uiAbsPartIdx = 0;
958  }
959#if BURST_IPCM
960  if( !bRD )
961  {
962    if( pcCU->getLastCUSucIPCMFlag() && pcCU->getIPCMFlag(uiAbsPartIdx) )
963    {
964      return;
965    }
966  }
967#endif 
968#if RWTH_SDC_DLT_B0036
969  if( !pcCU->getSlice()->isInterB() && pcCU->isIntra(uiAbsPartIdx) && pcCU->getSDCFlag(uiAbsPartIdx)  )
970  {
971    assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
972    return;
973  }
974#endif
975 
976  m_pcEntropyCoderIf->codePartSize( pcCU, uiAbsPartIdx, uiDepth );
977 
978#if RWTH_SDC_DLT_B0036
979  // code SDC flag now!
980  if( pcCU->getSlice()->isInterB() && pcCU->isIntra(uiAbsPartIdx) && pcCU->getSlice()->getSPS()->isDepth() )
981  {
982    // encode SDC flag
983    encodeSDCFlag(pcCU, uiAbsPartIdx, bRD);
984   
985    if( pcCU->getSDCFlag(uiAbsPartIdx) )
986    {
987      // part size is also known for SDC intra
988      assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
989    }
990  }
991#endif
992}
993
994/** Encode I_PCM information.
995 * \param pcCU pointer to CU
996 * \param uiAbsPartIdx CU index
997 * \param bRD flag indicating estimation or encoding
998 * \returns Void
999 */
1000Void TEncEntropy::encodeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
1001{
1002  if(!pcCU->getSlice()->getSPS()->getUsePCM()
1003    || pcCU->getWidth(uiAbsPartIdx) > (1<<pcCU->getSlice()->getSPS()->getPCMLog2MaxSize())
1004    || pcCU->getWidth(uiAbsPartIdx) < (1<<pcCU->getSlice()->getSPS()->getPCMLog2MinSize()))
1005  {
1006    return;
1007  }
1008 
1009#if RWTH_SDC_DLT_B0036
1010  if( pcCU->getSDCFlag(uiAbsPartIdx) )
1011  {
1012    return;
1013  }
1014#endif
1015 
1016  if( bRD )
1017  {
1018    uiAbsPartIdx = 0;
1019  }
1020 
1021#if BURST_IPCM
1022  Int numIPCM = 0;
1023  Bool firstIPCMFlag = false;
1024
1025  if( pcCU->getIPCMFlag(uiAbsPartIdx) )
1026  {
1027    numIPCM = 1;
1028    firstIPCMFlag = true;
1029
1030    if( !bRD )
1031    {
1032      numIPCM = pcCU->getNumSucIPCM();
1033      firstIPCMFlag = !pcCU->getLastCUSucIPCMFlag();
1034    }
1035  }
1036  m_pcEntropyCoderIf->codeIPCMInfo ( pcCU, uiAbsPartIdx, numIPCM, firstIPCMFlag);
1037#else
1038  m_pcEntropyCoderIf->codeIPCMInfo ( pcCU, uiAbsPartIdx );
1039#endif
1040
1041}
1042
1043#if UNIFIED_TRANSFORM_TREE
1044Void TEncEntropy::xEncodeTransform( TComDataCU* pcCU,UInt offsetLuma, UInt offsetChroma, UInt uiAbsPartIdx, UInt absTUPartIdx, UInt uiDepth, UInt width, UInt height, UInt uiTrIdx, UInt uiInnerQuadIdx, UInt& uiYCbfFront3, UInt& uiUCbfFront3, UInt& uiVCbfFront3, Bool& bCodeDQP )
1045#else
1046Void TEncEntropy::xEncodeTransformSubdiv( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt absTUPartIdx, UInt uiDepth, UInt uiInnerQuadIdx, UInt& uiYCbfFront3, UInt& uiUCbfFront3, UInt& uiVCbfFront3 )
1047#endif
1048{
1049  const UInt uiSubdiv = pcCU->getTransformIdx( uiAbsPartIdx ) + pcCU->getDepth( uiAbsPartIdx ) > uiDepth;
1050  const UInt uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()]+2 - uiDepth;
1051#if UNIFIED_TRANSFORM_TREE
1052  UInt cbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA    , uiTrIdx );
1053  UInt cbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
1054  UInt cbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
1055
1056  if(uiTrIdx==0)
1057  {
1058    m_bakAbsPartIdxCU = uiAbsPartIdx;
1059  }
1060  if( uiLog2TrafoSize == 2 )
1061  {
1062    UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
1063    if( ( uiAbsPartIdx % partNum ) == 0 )
1064    {
1065      m_uiBakAbsPartIdx   = uiAbsPartIdx;
1066      m_uiBakChromaOffset = offsetChroma;
1067    }
1068    else if( ( uiAbsPartIdx % partNum ) == (partNum - 1) )
1069    {
1070      cbfU = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
1071      cbfV = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
1072    }
1073  }
1074#endif // UNIFIED_TRANSFORM_TREE
1075  {//CABAC
1076    if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTRA && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
1077    {
1078      assert( uiSubdiv );
1079    }
1080    else if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) &&  (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) )
1081    {
1082      if ( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
1083      {
1084        assert( uiSubdiv );
1085      }
1086      else
1087      {
1088        assert(!uiSubdiv );
1089      }
1090    }
1091    else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
1092    {
1093      assert( uiSubdiv );
1094    }
1095    else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
1096    {
1097      assert( !uiSubdiv );
1098    }
1099    else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
1100    {
1101      assert( !uiSubdiv );
1102    }
1103    else
1104    {
1105      assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
1106      m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSubdiv, uiDepth );
1107    }
1108  }
1109
1110  {
1111    if( uiLog2TrafoSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
1112    {
1113      const UInt uiTrDepthCurr = uiDepth - pcCU->getDepth( uiAbsPartIdx );
1114      const Bool bFirstCbfOfCU = uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() || uiTrDepthCurr == 0;
1115      if( bFirstCbfOfCU || uiLog2TrafoSize > 2 )
1116      {
1117        if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr - 1 ) )
1118        {
1119          if ( uiInnerQuadIdx == 3 && uiUCbfFront3 == 0 && uiLog2TrafoSize < pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
1120          {
1121            uiUCbfFront3++;
1122          }
1123          else
1124          {
1125            m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr );
1126            uiUCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr );
1127          }
1128        }
1129        if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr - 1 ) )
1130        {
1131          if ( uiInnerQuadIdx == 3 && uiVCbfFront3 == 0 && uiLog2TrafoSize < pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize()  )
1132          {
1133            uiVCbfFront3++;
1134          }
1135          else
1136          {
1137            m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr );
1138            uiVCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr );
1139          }
1140        }
1141      }
1142      else if( uiLog2TrafoSize == 2 )
1143      {
1144        assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr - 1 ) );
1145        assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr - 1 ) );
1146       
1147        uiUCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr );
1148        uiVCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr );
1149      }
1150    }
1151   
1152    if( uiSubdiv )
1153    {
1154#if UNIFIED_TRANSFORM_TREE
1155      UInt size;
1156      width  >>= 1;
1157      height >>= 1;
1158      size = width*height;
1159      uiTrIdx++;
1160#endif // UNIFIED_TRANSFORM_TREE
1161      ++uiDepth;
1162#if UNIFIED_TRANSFORM_TREE
1163      const UInt partNum = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1);
1164#else
1165      const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1);
1166#endif
1167     
1168      UInt uiCurrentCbfY = 0;
1169      UInt uiCurrentCbfU = 0;
1170      UInt uiCurrentCbfV = 0;
1171     
1172#if UNIFIED_TRANSFORM_TREE
1173      UInt nsAddr = 0;
1174      nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, 0, uiDepth - pcCU->getDepth( uiAbsPartIdx ) );
1175      xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, nsAddr, uiDepth, width, height, uiTrIdx, 0, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV, bCodeDQP );
1176
1177      uiAbsPartIdx += partNum;  offsetLuma += size;  offsetChroma += (size>>2);
1178      nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, 1, uiDepth - pcCU->getDepth( uiAbsPartIdx ) );
1179      xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, nsAddr, uiDepth, width, height, uiTrIdx, 1, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV, bCodeDQP );
1180
1181      uiAbsPartIdx += partNum;  offsetLuma += size;  offsetChroma += (size>>2);
1182      nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, 2, uiDepth - pcCU->getDepth( uiAbsPartIdx ) );
1183      xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, nsAddr, uiDepth, width, height, uiTrIdx, 2, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV, bCodeDQP );
1184
1185      uiAbsPartIdx += partNum;  offsetLuma += size;  offsetChroma += (size>>2);
1186      nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, 3, uiDepth - pcCU->getDepth( uiAbsPartIdx ) );
1187      xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, nsAddr, uiDepth, width, height, uiTrIdx, 3, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV, bCodeDQP );     
1188#else // UNIFIED_TRANSFORM_TREE
1189      UInt nsAddr = 0;
1190      nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, 0, uiDepth - pcCU->getDepth( uiAbsPartIdx ) );
1191      xEncodeTransformSubdiv( pcCU, uiAbsPartIdx, nsAddr, uiDepth, 0, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV );
1192
1193      uiAbsPartIdx += uiQPartNum;
1194      nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, 1, uiDepth - pcCU->getDepth( uiAbsPartIdx ) );
1195      xEncodeTransformSubdiv( pcCU, uiAbsPartIdx, nsAddr, uiDepth, 1, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV );
1196
1197      uiAbsPartIdx += uiQPartNum;
1198      nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, 2, uiDepth - pcCU->getDepth( uiAbsPartIdx ) );
1199      xEncodeTransformSubdiv( pcCU, uiAbsPartIdx, nsAddr, uiDepth, 2, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV );
1200
1201      uiAbsPartIdx += uiQPartNum;
1202      nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, 3, uiDepth - pcCU->getDepth( uiAbsPartIdx ) );
1203      xEncodeTransformSubdiv( pcCU, uiAbsPartIdx, nsAddr, uiDepth, 3, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV );
1204#endif // UNIFIED_TRANSFORM_TREE
1205     
1206      uiYCbfFront3 += uiCurrentCbfY;
1207      uiUCbfFront3 += uiCurrentCbfU;
1208      uiVCbfFront3 += uiCurrentCbfV;
1209    }
1210    else
1211    {
1212      {
1213        DTRACE_CABAC_VL( g_nSymbolCounter++ );
1214        DTRACE_CABAC_T( "\tTrIdx: abspart=" );
1215        DTRACE_CABAC_V( uiAbsPartIdx );
1216        DTRACE_CABAC_T( "\tdepth=" );
1217        DTRACE_CABAC_V( uiDepth );
1218        DTRACE_CABAC_T( "\ttrdepth=" );
1219        DTRACE_CABAC_V( pcCU->getTransformIdx( uiAbsPartIdx ) );
1220        DTRACE_CABAC_T( "\n" );
1221      }
1222      UInt uiLumaTrMode, uiChromaTrMode;
1223      pcCU->convertTransIdx( uiAbsPartIdx, pcCU->getTransformIdx( uiAbsPartIdx ), uiLumaTrMode, uiChromaTrMode );
1224      if(pcCU->getPredictionMode( uiAbsPartIdx ) == MODE_INTER && pcCU->useNonSquarePU( uiAbsPartIdx ) )
1225      {
1226        pcCU->setNSQTIdxSubParts( uiLog2TrafoSize, uiAbsPartIdx, absTUPartIdx, uiLumaTrMode );
1227      }
1228      if( pcCU->getPredictionMode(uiAbsPartIdx) != MODE_INTRA && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, 0 ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, 0 ) )
1229      {
1230        assert( pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, 0 ) );
1231        //      printf( "saved one bin! " );
1232      }
1233      else
1234      {
1235        const UInt uiLog2CUSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - pcCU->getDepth( uiAbsPartIdx );
1236        if ( pcCU->getPredictionMode( uiAbsPartIdx ) != MODE_INTRA && uiInnerQuadIdx == 3 && uiYCbfFront3 == 0 && uiUCbfFront3 == 0 && uiVCbfFront3 == 0
1237            && ( uiLog2CUSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() + 1 || uiLog2TrafoSize < pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() ) )
1238        {     
1239          uiYCbfFront3++;
1240        }   
1241        else
1242        {
1243          m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA, uiLumaTrMode );
1244          uiYCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiLumaTrMode );
1245        }
1246      }
1247     
1248#if UNIFIED_TRANSFORM_TREE
1249      if ( cbfY || cbfU || cbfV )
1250      {
1251        // dQP: only for LCU once
1252        if ( pcCU->getSlice()->getPPS()->getUseDQP() )
1253        {
1254          if ( bCodeDQP )
1255          {
1256            encodeQP( pcCU, m_bakAbsPartIdxCU );
1257            bCodeDQP = false;
1258          }
1259        }
1260      }
1261      if( cbfY )
1262      {
1263        Int trWidth = width;
1264        Int trHeight = height;
1265        pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight );
1266        m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffY()+offsetLuma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_LUMA );
1267      }
1268      if( uiLog2TrafoSize > 2 )
1269      {
1270        Int trWidth = width >> 1;
1271        Int trHeight = height >> 1;
1272        pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight );
1273        if( cbfU )
1274        {
1275          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
1276        }
1277        if( cbfV )
1278        {
1279          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
1280        }
1281      }
1282      else
1283      {
1284        UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
1285        if( ( uiAbsPartIdx % partNum ) == (partNum - 1) )
1286        {
1287          Int trWidth = width;
1288          Int trHeight = height;
1289          pcCU->getNSQTSize( uiTrIdx - 1, uiAbsPartIdx, trWidth, trHeight );
1290          if( cbfU )
1291          {
1292            m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
1293          }
1294          if( cbfV )
1295          {
1296            m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
1297          }
1298        }
1299      }
1300#endif // UNIFIED_TRANSFORM_TREE
1301    }
1302  }
1303}
1304
1305#if !UNIFIED_TRANSFORM_TREE
1306// transform index
1307Void TEncEntropy::encodeTransformIdx( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
1308{
1309  assert( !bRD ); // parameter bRD can be removed
1310  if( bRD )
1311  {
1312    uiAbsPartIdx = 0;
1313  }
1314 
1315  DTRACE_CABAC_VL( g_nSymbolCounter++ )
1316  DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" )
1317  DTRACE_CABAC_V( uiDepth )
1318  DTRACE_CABAC_T( "\n" )
1319  UInt temp = 0;
1320  UInt temp1 = 0;
1321  UInt temp2 = 0;
1322  xEncodeTransformSubdiv( pcCU, uiAbsPartIdx, uiAbsPartIdx, uiDepth, 0, temp, temp1, temp2 );
1323}
1324#endif // !UNIFIED_TRANSFORM_TREE
1325
1326// Intra direction for Luma
1327Void TEncEntropy::encodeIntraDirModeLuma  ( TComDataCU* pcCU, UInt uiAbsPartIdx )
1328{
1329  m_pcEntropyCoderIf->codeIntraDirLumaAng( pcCU, uiAbsPartIdx );
1330}
1331
1332// Intra direction for Chroma
1333Void TEncEntropy::encodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
1334{
1335  if( bRD )
1336  {
1337    uiAbsPartIdx = 0;
1338  }
1339 
1340  m_pcEntropyCoderIf->codeIntraDirChroma( pcCU, uiAbsPartIdx );
1341}
1342
1343Void TEncEntropy::encodePredInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
1344{
1345  if( bRD )
1346  {
1347    uiAbsPartIdx = 0;
1348  }
1349 
1350#if RWTH_SDC_DLT_B0036
1351  if( pcCU->getSDCFlag(uiAbsPartIdx) )
1352  {
1353    encodeSDCPredMode(pcCU, uiAbsPartIdx, bRD);
1354    return;
1355  }
1356#endif
1357 
1358  PartSize eSize = pcCU->getPartitionSize( uiAbsPartIdx );
1359 
1360  if( pcCU->isIntra( uiAbsPartIdx ) )                                 // If it is Intra mode, encode intra prediction mode.
1361  {
1362    if( eSize == SIZE_NxN )                                         // if it is NxN size, encode 4 intra directions.
1363    {
1364      UInt uiPartOffset = ( pcCU->getPic()->getNumPartInCU() >> ( pcCU->getDepth(uiAbsPartIdx) << 1 ) ) >> 2;
1365      // if it is NxN size, this size might be the smallest partition size.
1366      encodeIntraDirModeLuma( pcCU, uiAbsPartIdx                  );
1367      encodeIntraDirModeLuma( pcCU, uiAbsPartIdx + uiPartOffset   );
1368      encodeIntraDirModeLuma( pcCU, uiAbsPartIdx + uiPartOffset*2 );
1369      encodeIntraDirModeLuma( pcCU, uiAbsPartIdx + uiPartOffset*3 );
1370      encodeIntraDirModeChroma( pcCU, uiAbsPartIdx, bRD );
1371    }
1372    else                                                              // if it is not NxN size, encode 1 intra directions
1373    {
1374      encodeIntraDirModeLuma  ( pcCU, uiAbsPartIdx );
1375      encodeIntraDirModeChroma( pcCU, uiAbsPartIdx, bRD );
1376    }
1377  }
1378  else                                                                // if it is Inter mode, encode motion vector and reference index
1379  {
1380    encodePUWise( pcCU, uiAbsPartIdx, bRD );
1381  }
1382}
1383
1384/** encode motion information for every PU block
1385 * \param pcCU
1386 * \param uiAbsPartIdx
1387 * \param bRD
1388 * \returns Void
1389 */
1390Void TEncEntropy::encodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
1391{
1392  if ( bRD )
1393  {
1394    uiAbsPartIdx = 0;
1395  }
1396 
1397  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
1398  UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) );
1399  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
1400  UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() - uiDepth ) << 1 ) ) >> 4;
1401
1402  for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset )
1403  {
1404    encodeMergeFlag( pcCU, uiSubPartIdx, uiPartIdx );
1405    if ( pcCU->getMergeFlag( uiSubPartIdx ) )
1406    {
1407      encodeMergeIndex( pcCU, uiSubPartIdx, uiPartIdx );
1408    }
1409    else
1410    {
1411      encodeInterDirPU( pcCU, uiSubPartIdx );
1412      for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
1413      {
1414        if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
1415        {
1416          encodeRefFrmIdxPU ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
1417          encodeMvdPU       ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
1418          encodeMVPIdxPU    ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
1419        }
1420      }
1421    }
1422  }
1423
1424  return;
1425}
1426
1427Void TEncEntropy::encodeInterDirPU( TComDataCU* pcCU, UInt uiAbsPartIdx )
1428{
1429  if ( !pcCU->getSlice()->isInterB() )
1430  {
1431    return;
1432  }
1433
1434  m_pcEntropyCoderIf->codeInterDir( pcCU, uiAbsPartIdx );
1435  return;
1436}
1437
1438/** encode reference frame index for a PU block
1439 * \param pcCU
1440 * \param uiAbsPartIdx
1441 * \param eRefList
1442 * \returns Void
1443 */
1444Void TEncEntropy::encodeRefFrmIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
1445{
1446  assert( !pcCU->isIntra( uiAbsPartIdx ) );
1447
1448  if(pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C)>0 && pcCU->getInterDir( uiAbsPartIdx ) != 3)
1449  {
1450    if ((eRefList== REF_PIC_LIST_1) || ( pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_C ) == 1 ) )
1451    {
1452      return;
1453    }
1454
1455    if ( pcCU->getSlice()->getNumRefIdx ( REF_PIC_LIST_C ) > 1 )
1456    {
1457      m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, RefPicList(pcCU->getInterDir( uiAbsPartIdx )-1) );
1458    }
1459
1460  }
1461  else
1462  {
1463    if ( ( pcCU->getSlice()->getNumRefIdx( eRefList ) == 1 ) )
1464    {
1465      return;
1466    }
1467
1468    if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
1469    {
1470      m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, eRefList );
1471    }
1472  }
1473
1474  return;
1475}
1476
1477/** encode motion vector difference for a PU block
1478 * \param pcCU
1479 * \param uiAbsPartIdx
1480 * \param eRefList
1481 * \returns Void
1482 */
1483Void TEncEntropy::encodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
1484{
1485  assert( !pcCU->isIntra( uiAbsPartIdx ) );
1486
1487  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
1488  {
1489    m_pcEntropyCoderIf->codeMvd( pcCU, uiAbsPartIdx, eRefList );
1490  }
1491  return;
1492}
1493
1494Void TEncEntropy::encodeMVPIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
1495{
1496  if ( (pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList )) && (pcCU->getAMVPMode(uiAbsPartIdx) == AM_EXPL) )
1497  {
1498#if HHI_INTER_VIEW_MOTION_PRED
1499    const Int iNumCands = AMVP_MAX_NUM_CANDS + ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 );
1500    m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList, iNumCands );
1501#else
1502    m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList );
1503#endif
1504  }
1505
1506  return;
1507}
1508
1509Void TEncEntropy::encodeQtCbf( TComDataCU* pcCU, UInt uiAbsPartIdx, TextType eType, UInt uiTrDepth )
1510{
1511  m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, eType, uiTrDepth );
1512}
1513
1514Void TEncEntropy::encodeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx )
1515{
1516  m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSymbol, uiCtx );
1517}
1518
1519Void TEncEntropy::encodeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx )
1520{
1521  m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
1522}
1523
1524// dQP
1525Void TEncEntropy::encodeQP( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
1526{
1527  if( bRD )
1528  {
1529    uiAbsPartIdx = 0;
1530  }
1531 
1532  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
1533  {
1534    m_pcEntropyCoderIf->codeDeltaQP( pcCU, uiAbsPartIdx );
1535  }
1536}
1537
1538
1539// texture
1540#if !UNIFIED_TRANSFORM_TREE
1541Void TEncEntropy::xEncodeCoeff( TComDataCU* pcCU, UInt uiLumaOffset, UInt uiChromaOffset, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, UInt uiTrIdx, UInt uiCurrTrIdx, Bool& bCodeDQP )
1542{
1543  UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth ] + 2;
1544  UInt uiCbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiTrIdx );
1545  UInt uiCbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
1546  UInt uiCbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
1547
1548  if( uiLog2TrSize == 2 )
1549  {
1550    UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
1551    if( ( uiAbsPartIdx % uiQPDiv ) == 0 )
1552    {
1553      m_uiBakAbsPartIdx   = uiAbsPartIdx;
1554      m_uiBakChromaOffset = uiChromaOffset;
1555    }
1556    else if( ( uiAbsPartIdx % uiQPDiv ) == (uiQPDiv - 1) )
1557    {
1558      uiCbfU = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
1559      uiCbfV = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
1560    }
1561  }
1562
1563  if ( uiCbfY || uiCbfU || uiCbfV )
1564  {
1565    // dQP: only for LCU once
1566    if ( pcCU->getSlice()->getPPS()->getUseDQP() )
1567    {
1568      if ( bCodeDQP )
1569      {
1570        encodeQP( pcCU, uiAbsPartIdx );
1571        bCodeDQP = false;
1572      }
1573    }
1574    UInt uiLumaTrMode, uiChromaTrMode;
1575    pcCU->convertTransIdx( uiAbsPartIdx, pcCU->getTransformIdx( uiAbsPartIdx ), uiLumaTrMode, uiChromaTrMode );
1576    const UInt uiStopTrMode = uiLumaTrMode;
1577   
1578    assert(1); // as long as quadtrees are not used for residual transform
1579   
1580    if( uiTrIdx == uiStopTrMode )
1581    {
1582      if( pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiTrIdx ) )
1583      {
1584        Int trWidth = uiWidth;
1585        Int trHeight = uiHeight;
1586        pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight );
1587        m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffY()+uiLumaOffset), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_LUMA );
1588      }
1589
1590      uiWidth  >>= 1;
1591      uiHeight >>= 1;
1592
1593      if( uiLog2TrSize == 2 )
1594      {
1595        UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
1596        if( ( uiAbsPartIdx % uiQPDiv ) == (uiQPDiv - 1) )
1597        {
1598          uiWidth  <<= 1;
1599          uiHeight <<= 1;
1600          Int trWidth = uiWidth;
1601          Int trHeight = uiHeight;
1602          pcCU->getNSQTSize( uiTrIdx-1, uiAbsPartIdx, trWidth, trHeight );
1603          if( pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_U, uiTrIdx ) )
1604          {
1605            m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
1606          }
1607          if( pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_V, uiTrIdx ) )
1608          {
1609            m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
1610          }
1611        }
1612      }
1613      else
1614      {
1615        Int trWidth = uiWidth;
1616        Int trHeight = uiHeight;
1617        pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight );
1618        if( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrIdx ) )
1619        {
1620          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+uiChromaOffset), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
1621        }
1622        if( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrIdx ) )
1623        {
1624          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+uiChromaOffset), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
1625        }
1626      }
1627    }
1628    else
1629    {
1630      {
1631        DTRACE_CABAC_VL( g_nSymbolCounter++ );
1632        DTRACE_CABAC_T( "\tgoing down\tdepth=" );
1633        DTRACE_CABAC_V( uiDepth );
1634        DTRACE_CABAC_T( "\ttridx=" );
1635        DTRACE_CABAC_V( uiTrIdx );
1636        DTRACE_CABAC_T( "\n" );
1637      }
1638      if( uiCurrTrIdx <= uiTrIdx )
1639        assert(1);
1640     
1641      UInt uiSize;
1642      uiWidth  >>= 1;
1643      uiHeight >>= 1;
1644      uiSize = uiWidth*uiHeight;
1645      uiDepth++;
1646      uiTrIdx++;
1647     
1648      UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1);
1649      UInt uiIdx      = uiAbsPartIdx;
1650     
1651      {
1652        xEncodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiIdx, uiDepth, uiWidth, uiHeight, uiTrIdx, uiCurrTrIdx, bCodeDQP );
1653        uiLumaOffset += uiSize;  uiChromaOffset += (uiSize>>2);  uiIdx += uiQPartNum;
1654
1655        xEncodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiIdx, uiDepth, uiWidth, uiHeight, uiTrIdx, uiCurrTrIdx, bCodeDQP );
1656        uiLumaOffset += uiSize;  uiChromaOffset += (uiSize>>2);  uiIdx += uiQPartNum;
1657
1658        xEncodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiIdx, uiDepth, uiWidth, uiHeight, uiTrIdx, uiCurrTrIdx, bCodeDQP );
1659        uiLumaOffset += uiSize;  uiChromaOffset += (uiSize>>2);  uiIdx += uiQPartNum;
1660
1661        xEncodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiIdx, uiDepth, uiWidth, uiHeight, uiTrIdx, uiCurrTrIdx, bCodeDQP );
1662      }
1663      {
1664        DTRACE_CABAC_VL( g_nSymbolCounter++ );
1665        DTRACE_CABAC_T( "\tgoing up\n" );
1666      }
1667    }
1668  }
1669}
1670#endif // !UNIFIED_TRANSFORM_TREE
1671
1672/** encode coefficients
1673 * \param pcCU
1674 * \param uiAbsPartIdx
1675 * \param uiDepth
1676 * \param uiWidth
1677 * \param uiHeight
1678 */
1679Void TEncEntropy::encodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, Bool& bCodeDQP )
1680{
1681  UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
1682  UInt uiLumaOffset   = uiMinCoeffSize*uiAbsPartIdx;
1683  UInt uiChromaOffset = uiLumaOffset>>2;
1684 
1685  UInt uiLumaTrMode, uiChromaTrMode;
1686  pcCU->convertTransIdx( uiAbsPartIdx, pcCU->getTransformIdx(uiAbsPartIdx), uiLumaTrMode, uiChromaTrMode );
1687 
1688#if RWTH_SDC_DLT_B0036
1689  if( pcCU->getSDCFlag( uiAbsPartIdx ) )
1690  {
1691    assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
1692    assert( pcCU->getTransformIdx(uiAbsPartIdx) == 0 );
1693    assert( pcCU->getCbf(uiAbsPartIdx, TEXT_LUMA) == 1 );
1694    assert( pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_U) == 1 );
1695    assert( pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_V) == 1 );
1696   
1697    encodeSDCResidualData(pcCU, uiAbsPartIdx);
1698    return;
1699  }
1700#endif
1701 
1702  if( pcCU->isIntra(uiAbsPartIdx) )
1703  {
1704    DTRACE_CABAC_VL( g_nSymbolCounter++ )
1705    DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" )
1706    DTRACE_CABAC_V( uiDepth )
1707    DTRACE_CABAC_T( "\n" )
1708#if !UNIFIED_TRANSFORM_TREE
1709    UInt temp = 0;
1710    UInt temp1 = 0;
1711    UInt temp2 = 0;
1712    xEncodeTransformSubdiv( pcCU, uiAbsPartIdx, uiAbsPartIdx, uiDepth, 0, temp, temp1, temp2 );
1713#endif // !UNIFIED_TRANSFORM_TREE
1714  }
1715  else
1716  {
1717    {
1718#if HHI_MPI
1719      if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N &&
1720            ( pcCU->getTextureModeDepth( uiAbsPartIdx ) == -1 || uiDepth == pcCU->getTextureModeDepth( uiAbsPartIdx ) ) ) )
1721#else
1722      if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ) )
1723#endif
1724      {
1725        m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
1726      }
1727      if ( !pcCU->getQtRootCbf( uiAbsPartIdx ) )
1728      {
1729#if 1 // MW Bug Fix
1730        pcCU->setCbfSubParts( 0, 0, 0, uiAbsPartIdx, uiDepth );
1731        pcCU->setTrIdxSubParts( 0 , uiAbsPartIdx, uiDepth );
1732#endif
1733        pcCU->setNSQTIdxSubParts( uiAbsPartIdx, uiDepth );
1734        return;
1735      }
1736    }
1737#if !UNIFIED_TRANSFORM_TREE
1738    encodeTransformIdx( pcCU, uiAbsPartIdx, pcCU->getDepth(uiAbsPartIdx) );
1739#endif
1740  }
1741 
1742#if UNIFIED_TRANSFORM_TREE
1743  UInt temp = 0;
1744  UInt temp1 = 0;
1745  UInt temp2 = 0;
1746  xEncodeTransform( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, 0, temp, temp1, temp2, bCodeDQP );
1747#else // UNIFIED_TRANSFORM_TREE
1748  xEncodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, uiLumaTrMode, bCodeDQP );
1749#endif // UNIFIED_TRANSFORM_TREE
1750}
1751
1752Void TEncEntropy::encodeCoeffNxN( TComDataCU* pcCU, TCoeff* pcCoeff, UInt uiAbsPartIdx, UInt uiTrWidth, UInt uiTrHeight, UInt uiDepth, TextType eType )
1753{ // This is for Transform unit processing. This may be used at mode selection stage for Inter.
1754  m_pcEntropyCoderIf->codeCoeffNxN( pcCU, pcCoeff, uiAbsPartIdx, uiTrWidth, uiTrHeight, uiDepth, eType );
1755}
1756
1757Void TEncEntropy::estimateBit (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, TextType eTType)
1758{ 
1759  eTType = eTType == TEXT_LUMA ? TEXT_LUMA : TEXT_CHROMA;
1760 
1761  m_pcEntropyCoderIf->estBit ( pcEstBitsSbac, width, height, eTType );
1762}
1763
1764#if SAO_UNIT_INTERLEAVING
1765/** Encode SAO Offset
1766 * \param  saoLcuParam SAO LCU paramters
1767 */
1768Void TEncEntropy::encodeSaoOffset(SaoLcuParam* saoLcuParam)
1769{
1770  UInt uiSymbol;
1771  Int i;
1772
1773  uiSymbol = saoLcuParam->typeIdx + 1;
1774  m_pcEntropyCoderIf->codeSaoTypeIdx(uiSymbol);
1775  if (uiSymbol)
1776  {
1777    if( saoLcuParam->typeIdx == SAO_BO )
1778    {
1779      // Code Left Band Index
1780      uiSymbol = (UInt) (saoLcuParam->bandPosition);
1781      m_pcEntropyCoderIf->codeSaoUflc(uiSymbol);
1782      for( i=0; i< saoLcuParam->length; i++)
1783      {
1784        m_pcEntropyCoderIf->codeSaoSvlc(saoLcuParam->offset[i]);
1785      } 
1786    }
1787    else
1788      if( saoLcuParam->typeIdx < 4 )
1789      {
1790        m_pcEntropyCoderIf->codeSaoUvlc( saoLcuParam->offset[0]);
1791        m_pcEntropyCoderIf->codeSaoUvlc( saoLcuParam->offset[1]);
1792        m_pcEntropyCoderIf->codeSaoUvlc(-saoLcuParam->offset[2]);
1793        m_pcEntropyCoderIf->codeSaoUvlc(-saoLcuParam->offset[3]);
1794      }
1795  }
1796}
1797/** Encode SAO unit
1798* \param  rx
1799* \param  ry
1800* \param  iCompIdx
1801* \param  pSaoParam
1802* \param  bRepeatedRow
1803 */
1804Void TEncEntropy::encodeSaoUnit(Int rx, Int ry, Int compIdx, SAOParam* saoParam, Int repeatedRow )
1805{
1806  int addr, addrLeft; 
1807  int numCuInWidth  = saoParam->numCuInWidth;
1808  SaoLcuParam* saoOneLcu;
1809  Int runLeft;
1810
1811  addr      =  rx + ry*numCuInWidth;
1812  addrLeft  =  (addr%numCuInWidth == 0) ? -1 : addr - 1;
1813
1814  if (!repeatedRow)
1815  {
1816    saoOneLcu = &(saoParam->saoLcuParam[compIdx][addr]);   
1817    runLeft = (addrLeft>=0 ) ? saoParam->saoLcuParam[compIdx][addrLeft].run : -1;
1818    if (rx == 0 || runLeft==0)
1819    {
1820      if (ry == 0)
1821      {
1822        m_pcEntropyCoderIf->codeSaoRun(saoOneLcu->runDiff, numCuInWidth-rx-1); 
1823        saoOneLcu->mergeUpFlag = 0;
1824      }
1825      else 
1826      {
1827        m_pcEntropyCoderIf->codeSaoSvlc(saoOneLcu->runDiff); 
1828        m_pcEntropyCoderIf->codeSaoFlag(saoOneLcu->mergeUpFlag); 
1829      }
1830      if (!saoOneLcu->mergeUpFlag)
1831      {
1832        encodeSaoOffset(saoOneLcu);
1833      }
1834    }
1835  }
1836}
1837
1838/** Encode SAO unit interleaving
1839* \param  rx
1840* \param  ry
1841* \param  pSaoParam
1842* \param  pcCU
1843* \param  iCUAddrInSlice
1844* \param  iCUAddrUpInSlice
1845* \param  bLFCrossSliceBoundaryFlag
1846 */
1847Void TEncEntropy::encodeSaoUnitInterleaving(Int rx, Int ry, SAOParam* saoParam, TComDataCU* cu, Int cuAddrInSlice, Int cuAddrUpInSlice, Bool lfCrossSliceBoundaryFlag)
1848{
1849  Int addr = cu->getAddr();
1850  for (Int compIdx=0; compIdx<3; compIdx++)
1851  {
1852    if (saoParam->bSaoFlag[compIdx])
1853    {
1854      if (rx>0 && cuAddrInSlice!=0)
1855      {
1856      m_pcEntropyCoderIf->codeSaoMergeLeft(saoParam->saoLcuParam[compIdx][addr].mergeLeftFlag,compIdx);
1857      }
1858      else
1859      {
1860        saoParam->saoLcuParam[compIdx][addr].mergeLeftFlag = 0;
1861      }
1862      if (saoParam->saoLcuParam[compIdx][addr].mergeLeftFlag == 0)
1863      {
1864        if ( (ry > 0) && (cuAddrUpInSlice>0||lfCrossSliceBoundaryFlag))
1865        {
1866          m_pcEntropyCoderIf->codeSaoMergeUp(saoParam->saoLcuParam[compIdx][addr].mergeUpFlag);
1867        }
1868        else
1869        {
1870          saoParam->saoLcuParam[compIdx][addr].mergeUpFlag = 0;
1871        }
1872        if (!saoParam->saoLcuParam[compIdx][addr].mergeUpFlag)
1873        {
1874          encodeSaoOffset(&(saoParam->saoLcuParam[compIdx][addr]));
1875        }
1876      }
1877    }
1878  }
1879}
1880
1881/** Encode SAO parameter
1882* \param  pcAPS
1883 */
1884Void TEncEntropy::encodeSaoParam(TComAPS* aps)
1885{
1886  SaoLcuParam* psSaoOneLcu;
1887  int i,j,k, compIdx; 
1888  int numCuInWidth  ;
1889  int numCuInHeight ;
1890  Bool repeatedRow[3];
1891  Int addr;
1892  m_pcEntropyCoderIf->codeSaoFlag(aps->getSaoInterleavingFlag()); 
1893  if(!aps->getSaoInterleavingFlag())
1894  {
1895    m_pcEntropyCoderIf->codeSaoFlag(aps->getSaoEnabled()); 
1896    if (aps->getSaoEnabled())
1897    {
1898      SAOParam* pSaoParam = aps->getSaoParam();
1899      numCuInWidth  = pSaoParam->numCuInWidth;
1900      numCuInHeight = pSaoParam->numCuInHeight;
1901      m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->bSaoFlag[1]); 
1902      m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->bSaoFlag[2]); 
1903      m_pcEntropyCoderIf->codeSaoUvlc(numCuInWidth-1); 
1904      m_pcEntropyCoderIf->codeSaoUvlc(numCuInHeight-1); 
1905      for (compIdx=0;compIdx<3;compIdx++)
1906      {
1907        if (pSaoParam->bSaoFlag[compIdx])
1908        {
1909          m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->oneUnitFlag[compIdx]); 
1910          if (pSaoParam->oneUnitFlag[compIdx])
1911          {
1912            psSaoOneLcu = &(pSaoParam->saoLcuParam[compIdx][0]);   
1913            encodeSaoOffset(psSaoOneLcu);
1914          }
1915        }
1916      }
1917
1918      for (j=0;j<numCuInHeight;j++)
1919      {
1920        for (compIdx=0; compIdx<3; compIdx++)
1921        {
1922          repeatedRow[compIdx] = true;
1923          for (k=0;k<numCuInWidth;k++)
1924          {
1925            addr       =  k + j*numCuInWidth;
1926            psSaoOneLcu = &(pSaoParam->saoLcuParam[compIdx][addr]);   
1927            if (!psSaoOneLcu->mergeUpFlag || psSaoOneLcu->runDiff)
1928            {
1929              repeatedRow[compIdx] = false;
1930              break;
1931            }
1932          }
1933        }
1934        for (i=0;i<numCuInWidth;i++)
1935        {
1936          for (compIdx=0; compIdx<3; compIdx++)
1937          {
1938            if (pSaoParam->bSaoFlag[compIdx]  && !pSaoParam->oneUnitFlag[compIdx]) 
1939            {
1940              if (j>0 && i==0) 
1941              {
1942                m_pcEntropyCoderIf->codeSaoFlag(repeatedRow[compIdx]); 
1943              }
1944              encodeSaoUnit (i,j, compIdx, pSaoParam, repeatedRow[compIdx]);
1945            }
1946          }
1947        }
1948      }
1949    }
1950  }
1951}
1952#else
1953/** Encode SAO for one partition
1954 * \param  pSaoParam, iPartIdx
1955 */
1956Void TEncEntropy::encodeSaoOnePart(SAOParam* pSaoParam, Int iPartIdx, Int iYCbCr)
1957{
1958  SAOQTPart*  pAlfPart = NULL;
1959  pAlfPart = &(pSaoParam->psSaoPart[iYCbCr][iPartIdx]); 
1960
1961  UInt uiSymbol;
1962
1963  if(!pAlfPart->bSplit)
1964  {
1965    if (pAlfPart->bEnableFlag)
1966    {
1967      uiSymbol = pAlfPart->iBestType + 1;
1968    }
1969    else
1970    {
1971      uiSymbol = 0;
1972    }
1973   
1974    m_pcEntropyCoderIf->codeSaoUvlc(uiSymbol);
1975
1976    if (pAlfPart->bEnableFlag)
1977    {
1978      for(Int i=0; i< pAlfPart->iLength; i++)
1979      {
1980        m_pcEntropyCoderIf->codeSaoSvlc(pAlfPart->iOffset[i]);
1981      }   
1982    }
1983    return;
1984  }
1985
1986  //split
1987  if (pAlfPart->PartLevel < pSaoParam->iMaxSplitLevel)
1988  {
1989    for (Int i=0;i<NUM_DOWN_PART;i++)
1990    {
1991      encodeSaoOnePart(pSaoParam, pAlfPart->DownPartsIdx[i], iYCbCr);
1992    }
1993  }
1994}
1995
1996/** Encode quadtree split flag
1997 * \param  pSaoParam, iPartIdx
1998 */
1999Void TEncEntropy::encodeQuadTreeSplitFlag(SAOParam* pSaoParam, Int iPartIdx, Int iYCbCr)
2000{
2001  SAOQTPart*  pSaoPart = NULL;
2002  pSaoPart = &(pSaoParam->psSaoPart[iYCbCr][iPartIdx]);
2003
2004  if(pSaoPart->PartLevel < pSaoParam->iMaxSplitLevel)
2005  {
2006    //send one flag
2007    m_pcEntropyCoderIf->codeSaoFlag( (pSaoPart->bSplit)?(1):(0)  );
2008
2009    if(pSaoPart->bSplit)
2010    {
2011      for (Int i=0;i<NUM_DOWN_PART;i++)
2012      {
2013        encodeQuadTreeSplitFlag(pSaoParam, pSaoPart->DownPartsIdx[i], iYCbCr);
2014      }
2015    } 
2016  }
2017}
2018/** Encode SAO parameters
2019 * \param  pSaoParam
2020 */
2021Void TEncEntropy::encodeSaoParam(SAOParam* pSaoParam)
2022{
2023  if (pSaoParam->bSaoFlag[0])
2024  {
2025    encodeQuadTreeSplitFlag(pSaoParam, 0, 0);
2026    encodeSaoOnePart(pSaoParam, 0, 0);
2027    m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->bSaoFlag[1]); 
2028    if (pSaoParam->bSaoFlag[1])
2029    {
2030      encodeQuadTreeSplitFlag(pSaoParam, 0, 1);
2031      encodeSaoOnePart(pSaoParam, 0, 1);
2032    }
2033    m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->bSaoFlag[2]); 
2034    if (pSaoParam->bSaoFlag[2])
2035    {
2036      encodeQuadTreeSplitFlag(pSaoParam, 0, 2);
2037      encodeSaoOnePart(pSaoParam, 0, 2);
2038    }
2039  }
2040}
2041#endif
2042
2043Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
2044{
2045  Int count = 0;
2046 
2047  for ( Int i = 0; i < uiSize; i++ )
2048  {
2049    count += pcCoef[i] != 0;
2050  }
2051 
2052  return count;
2053}
2054
2055/** encode quantization matrix
2056 * \param scalingList quantization matrix information
2057 */
2058Void TEncEntropy::encodeScalingList( TComScalingList* scalingList )
2059{
2060  m_pcEntropyCoderIf->codeScalingList( scalingList );
2061}
2062
2063Void TEncEntropy::encodeDFParams(TComAPS* pcAPS)
2064{
2065  m_pcEntropyCoderIf->codeDFFlag(pcAPS->getLoopFilterDisable(), "loop_filter_disable");
2066
2067  if (!pcAPS->getLoopFilterDisable())
2068  {
2069    m_pcEntropyCoderIf->codeDFSvlc(pcAPS->getLoopFilterBetaOffset(), "beta_offset_div2");
2070    m_pcEntropyCoderIf->codeDFSvlc(pcAPS->getLoopFilterTcOffset(), "tc_offset_div2");
2071  }
2072}
2073
2074#if RWTH_SDC_DLT_B0036
2075Void TEncEntropy::encodeSDCPredMode( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
2076{
2077  assert( pcCU->getSlice()->getSPS()->isDepth() );
2078 
2079  if( bRD )
2080    uiAbsPartIdx = 0;
2081 
2082  m_pcEntropyCoderIf->codeSDCPredMode(pcCU, uiAbsPartIdx);
2083}
2084
2085Void TEncEntropy::encodeSDCFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
2086{
2087  assert( pcCU->getSlice()->getSPS()->isDepth() );
2088 
2089  if( bRD )
2090    uiAbsPartIdx = 0;
2091 
2092  m_pcEntropyCoderIf->codeSDCFlag(pcCU, uiAbsPartIdx);
2093}
2094
2095Void TEncEntropy::encodeSDCResidualData( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
2096{
2097  assert( pcCU->getSlice()->getSPS()->isDepth() );
2098  assert( pcCU->getCbf(uiAbsPartIdx, TEXT_LUMA) == 1 );
2099  assert( pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_U) == 1 );
2100  assert( pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_V) == 1 );
2101  assert( pcCU->getTransformIdx(uiAbsPartIdx) == 0 );
2102 
2103  if( bRD )
2104    uiAbsPartIdx = 0;
2105 
2106  // number of segments depends on prediction mode for INTRA
2107  UInt uiNumSegments = 2;
2108  UInt uiLumaPredMode = pcCU->getLumaIntraDir( uiAbsPartIdx );
2109  if( uiLumaPredMode == DC_IDX || uiLumaPredMode == PLANAR_IDX )
2110    uiNumSegments = 1;
2111 
2112  // encode residual data for each segment
2113  for( UInt uiSeg = 0; uiSeg < uiNumSegments; uiSeg++ )
2114    m_pcEntropyCoderIf->codeSDCResidualData(pcCU, uiAbsPartIdx, uiSeg);
2115}
2116#endif
2117
2118//! \}
Note: See TracBrowser for help on using the repository browser.