source: 3DVCSoftware/branches/HTM-3.0-Vidyo/source/Lib/TLibEncoder/TEncEntropy.cpp @ 70

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