source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncEntropy.cpp @ 56

Last change on this file since 56 was 56, checked in by hschwarz, 12 years ago

updated trunk (move to HM6.1)

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