source: 3DVCSoftware/branches/HTM-4.1-dev1-HHI/source/Lib/TLibEncoder/TEncEntropy.cpp @ 204

Last change on this file since 204 was 171, checked in by intel-htm, 12 years ago

Here is the integrated software of B0065 from Intel. The corresponding simulation results was sent to Gerhard. The results demonstrated that B0065 has no impact of CTC.

  • Property svn:eol-style set to native
File size: 58.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 FIX_MPI_B0065
1659  if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getMergeIndex( uiAbsPartIdx ) == 0 && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N && pcCU->getTextureModeDepth( uiAbsPartIdx ) != -1 )
1660  {
1661    TComDataCU *pcTextureCU = pcCU->getSlice()->getTexturePic()->getCU( pcCU->getAddr() );
1662    if( uiDepth == pcTextureCU->getDepth(uiAbsPartIdx))
1663    {
1664      PartSize partSize = pcTextureCU->getPartitionSize(uiAbsPartIdx);
1665      pcCU->setPartSizeSubParts( partSize, uiAbsPartIdx, uiDepth );
1666    }
1667    else
1668    {
1669      pcCU->setPartSizeSubParts( SIZE_NxN, uiAbsPartIdx, uiDepth );
1670    }
1671  }
1672#endif
1673
1674#if UNIFIED_TRANSFORM_TREE
1675  UInt temp = 0;
1676  UInt temp1 = 0;
1677  UInt temp2 = 0;
1678  xEncodeTransform( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, 0, temp, temp1, temp2, bCodeDQP );
1679#else // UNIFIED_TRANSFORM_TREE
1680  xEncodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, uiLumaTrMode, bCodeDQP );
1681#endif // UNIFIED_TRANSFORM_TREE
1682
1683#if FIX_MPI_B0065
1684  if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getMergeIndex( uiAbsPartIdx ) == 0 && pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N &&  pcCU->getTextureModeDepth( uiAbsPartIdx ) != -1 )
1685  {
1686    pcCU->setPartSizeSubParts( SIZE_2Nx2N, uiAbsPartIdx, uiDepth ); 
1687  }
1688#endif
1689}
1690
1691Void TEncEntropy::encodeCoeffNxN( TComDataCU* pcCU, TCoeff* pcCoeff, UInt uiAbsPartIdx, UInt uiTrWidth, UInt uiTrHeight, UInt uiDepth, TextType eType )
1692{ // This is for Transform unit processing. This may be used at mode selection stage for Inter.
1693  m_pcEntropyCoderIf->codeCoeffNxN( pcCU, pcCoeff, uiAbsPartIdx, uiTrWidth, uiTrHeight, uiDepth, eType );
1694}
1695
1696Void TEncEntropy::estimateBit (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, TextType eTType)
1697{ 
1698  eTType = eTType == TEXT_LUMA ? TEXT_LUMA : TEXT_CHROMA;
1699 
1700  m_pcEntropyCoderIf->estBit ( pcEstBitsSbac, width, height, eTType );
1701}
1702
1703#if SAO_UNIT_INTERLEAVING
1704/** Encode SAO Offset
1705 * \param  saoLcuParam SAO LCU paramters
1706 */
1707Void TEncEntropy::encodeSaoOffset(SaoLcuParam* saoLcuParam)
1708{
1709  UInt uiSymbol;
1710  Int i;
1711
1712  uiSymbol = saoLcuParam->typeIdx + 1;
1713  m_pcEntropyCoderIf->codeSaoTypeIdx(uiSymbol);
1714  if (uiSymbol)
1715  {
1716    if( saoLcuParam->typeIdx == SAO_BO )
1717    {
1718      // Code Left Band Index
1719      uiSymbol = (UInt) (saoLcuParam->bandPosition);
1720      m_pcEntropyCoderIf->codeSaoUflc(uiSymbol);
1721      for( i=0; i< saoLcuParam->length; i++)
1722      {
1723        m_pcEntropyCoderIf->codeSaoSvlc(saoLcuParam->offset[i]);
1724      } 
1725    }
1726    else
1727      if( saoLcuParam->typeIdx < 4 )
1728      {
1729        m_pcEntropyCoderIf->codeSaoUvlc( saoLcuParam->offset[0]);
1730        m_pcEntropyCoderIf->codeSaoUvlc( saoLcuParam->offset[1]);
1731        m_pcEntropyCoderIf->codeSaoUvlc(-saoLcuParam->offset[2]);
1732        m_pcEntropyCoderIf->codeSaoUvlc(-saoLcuParam->offset[3]);
1733      }
1734  }
1735}
1736/** Encode SAO unit
1737* \param  rx
1738* \param  ry
1739* \param  iCompIdx
1740* \param  pSaoParam
1741* \param  bRepeatedRow
1742 */
1743Void TEncEntropy::encodeSaoUnit(Int rx, Int ry, Int compIdx, SAOParam* saoParam, Int repeatedRow )
1744{
1745  int addr, addrLeft; 
1746  int numCuInWidth  = saoParam->numCuInWidth;
1747  SaoLcuParam* saoOneLcu;
1748  Int runLeft;
1749
1750  addr      =  rx + ry*numCuInWidth;
1751  addrLeft  =  (addr%numCuInWidth == 0) ? -1 : addr - 1;
1752
1753  if (!repeatedRow)
1754  {
1755    saoOneLcu = &(saoParam->saoLcuParam[compIdx][addr]);   
1756    runLeft = (addrLeft>=0 ) ? saoParam->saoLcuParam[compIdx][addrLeft].run : -1;
1757    if (rx == 0 || runLeft==0)
1758    {
1759      if (ry == 0)
1760      {
1761        m_pcEntropyCoderIf->codeSaoRun(saoOneLcu->runDiff, numCuInWidth-rx-1); 
1762        saoOneLcu->mergeUpFlag = 0;
1763      }
1764      else 
1765      {
1766        m_pcEntropyCoderIf->codeSaoSvlc(saoOneLcu->runDiff); 
1767        m_pcEntropyCoderIf->codeSaoFlag(saoOneLcu->mergeUpFlag); 
1768      }
1769      if (!saoOneLcu->mergeUpFlag)
1770      {
1771        encodeSaoOffset(saoOneLcu);
1772      }
1773    }
1774  }
1775}
1776
1777/** Encode SAO unit interleaving
1778* \param  rx
1779* \param  ry
1780* \param  pSaoParam
1781* \param  pcCU
1782* \param  iCUAddrInSlice
1783* \param  iCUAddrUpInSlice
1784* \param  bLFCrossSliceBoundaryFlag
1785 */
1786Void TEncEntropy::encodeSaoUnitInterleaving(Int rx, Int ry, SAOParam* saoParam, TComDataCU* cu, Int cuAddrInSlice, Int cuAddrUpInSlice, Bool lfCrossSliceBoundaryFlag)
1787{
1788  Int addr = cu->getAddr();
1789  for (Int compIdx=0; compIdx<3; compIdx++)
1790  {
1791    if (saoParam->bSaoFlag[compIdx])
1792    {
1793      if (rx>0 && cuAddrInSlice!=0)
1794      {
1795      m_pcEntropyCoderIf->codeSaoMergeLeft(saoParam->saoLcuParam[compIdx][addr].mergeLeftFlag,compIdx);
1796      }
1797      else
1798      {
1799        saoParam->saoLcuParam[compIdx][addr].mergeLeftFlag = 0;
1800      }
1801      if (saoParam->saoLcuParam[compIdx][addr].mergeLeftFlag == 0)
1802      {
1803        if ( (ry > 0) && (cuAddrUpInSlice>0||lfCrossSliceBoundaryFlag))
1804        {
1805          m_pcEntropyCoderIf->codeSaoMergeUp(saoParam->saoLcuParam[compIdx][addr].mergeUpFlag);
1806        }
1807        else
1808        {
1809          saoParam->saoLcuParam[compIdx][addr].mergeUpFlag = 0;
1810        }
1811        if (!saoParam->saoLcuParam[compIdx][addr].mergeUpFlag)
1812        {
1813          encodeSaoOffset(&(saoParam->saoLcuParam[compIdx][addr]));
1814        }
1815      }
1816    }
1817  }
1818}
1819
1820/** Encode SAO parameter
1821* \param  pcAPS
1822 */
1823Void TEncEntropy::encodeSaoParam(TComAPS* aps)
1824{
1825  SaoLcuParam* psSaoOneLcu;
1826  int i,j,k, compIdx; 
1827  int numCuInWidth  ;
1828  int numCuInHeight ;
1829  Bool repeatedRow[3];
1830  Int addr;
1831  m_pcEntropyCoderIf->codeSaoFlag(aps->getSaoInterleavingFlag()); 
1832  if(!aps->getSaoInterleavingFlag())
1833  {
1834    m_pcEntropyCoderIf->codeSaoFlag(aps->getSaoEnabled()); 
1835    if (aps->getSaoEnabled())
1836    {
1837      SAOParam* pSaoParam = aps->getSaoParam();
1838      numCuInWidth  = pSaoParam->numCuInWidth;
1839      numCuInHeight = pSaoParam->numCuInHeight;
1840      m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->bSaoFlag[1]); 
1841      m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->bSaoFlag[2]); 
1842      m_pcEntropyCoderIf->codeSaoUvlc(numCuInWidth-1); 
1843      m_pcEntropyCoderIf->codeSaoUvlc(numCuInHeight-1); 
1844      for (compIdx=0;compIdx<3;compIdx++)
1845      {
1846        if (pSaoParam->bSaoFlag[compIdx])
1847        {
1848          m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->oneUnitFlag[compIdx]); 
1849          if (pSaoParam->oneUnitFlag[compIdx])
1850          {
1851            psSaoOneLcu = &(pSaoParam->saoLcuParam[compIdx][0]);   
1852            encodeSaoOffset(psSaoOneLcu);
1853          }
1854        }
1855      }
1856
1857      for (j=0;j<numCuInHeight;j++)
1858      {
1859        for (compIdx=0; compIdx<3; compIdx++)
1860        {
1861          repeatedRow[compIdx] = true;
1862          for (k=0;k<numCuInWidth;k++)
1863          {
1864            addr       =  k + j*numCuInWidth;
1865            psSaoOneLcu = &(pSaoParam->saoLcuParam[compIdx][addr]);   
1866            if (!psSaoOneLcu->mergeUpFlag || psSaoOneLcu->runDiff)
1867            {
1868              repeatedRow[compIdx] = false;
1869              break;
1870            }
1871          }
1872        }
1873        for (i=0;i<numCuInWidth;i++)
1874        {
1875          for (compIdx=0; compIdx<3; compIdx++)
1876          {
1877            if (pSaoParam->bSaoFlag[compIdx]  && !pSaoParam->oneUnitFlag[compIdx]) 
1878            {
1879              if (j>0 && i==0) 
1880              {
1881                m_pcEntropyCoderIf->codeSaoFlag(repeatedRow[compIdx]); 
1882              }
1883              encodeSaoUnit (i,j, compIdx, pSaoParam, repeatedRow[compIdx]);
1884            }
1885          }
1886        }
1887      }
1888    }
1889  }
1890}
1891#else
1892/** Encode SAO for one partition
1893 * \param  pSaoParam, iPartIdx
1894 */
1895Void TEncEntropy::encodeSaoOnePart(SAOParam* pSaoParam, Int iPartIdx, Int iYCbCr)
1896{
1897  SAOQTPart*  pAlfPart = NULL;
1898  pAlfPart = &(pSaoParam->psSaoPart[iYCbCr][iPartIdx]); 
1899
1900  UInt uiSymbol;
1901
1902  if(!pAlfPart->bSplit)
1903  {
1904    if (pAlfPart->bEnableFlag)
1905    {
1906      uiSymbol = pAlfPart->iBestType + 1;
1907    }
1908    else
1909    {
1910      uiSymbol = 0;
1911    }
1912   
1913    m_pcEntropyCoderIf->codeSaoUvlc(uiSymbol);
1914
1915    if (pAlfPart->bEnableFlag)
1916    {
1917      for(Int i=0; i< pAlfPart->iLength; i++)
1918      {
1919        m_pcEntropyCoderIf->codeSaoSvlc(pAlfPart->iOffset[i]);
1920      }   
1921    }
1922    return;
1923  }
1924
1925  //split
1926  if (pAlfPart->PartLevel < pSaoParam->iMaxSplitLevel)
1927  {
1928    for (Int i=0;i<NUM_DOWN_PART;i++)
1929    {
1930      encodeSaoOnePart(pSaoParam, pAlfPart->DownPartsIdx[i], iYCbCr);
1931    }
1932  }
1933}
1934
1935/** Encode quadtree split flag
1936 * \param  pSaoParam, iPartIdx
1937 */
1938Void TEncEntropy::encodeQuadTreeSplitFlag(SAOParam* pSaoParam, Int iPartIdx, Int iYCbCr)
1939{
1940  SAOQTPart*  pSaoPart = NULL;
1941  pSaoPart = &(pSaoParam->psSaoPart[iYCbCr][iPartIdx]);
1942
1943  if(pSaoPart->PartLevel < pSaoParam->iMaxSplitLevel)
1944  {
1945    //send one flag
1946    m_pcEntropyCoderIf->codeSaoFlag( (pSaoPart->bSplit)?(1):(0)  );
1947
1948    if(pSaoPart->bSplit)
1949    {
1950      for (Int i=0;i<NUM_DOWN_PART;i++)
1951      {
1952        encodeQuadTreeSplitFlag(pSaoParam, pSaoPart->DownPartsIdx[i], iYCbCr);
1953      }
1954    } 
1955  }
1956}
1957/** Encode SAO parameters
1958 * \param  pSaoParam
1959 */
1960Void TEncEntropy::encodeSaoParam(SAOParam* pSaoParam)
1961{
1962  if (pSaoParam->bSaoFlag[0])
1963  {
1964    encodeQuadTreeSplitFlag(pSaoParam, 0, 0);
1965    encodeSaoOnePart(pSaoParam, 0, 0);
1966    m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->bSaoFlag[1]); 
1967    if (pSaoParam->bSaoFlag[1])
1968    {
1969      encodeQuadTreeSplitFlag(pSaoParam, 0, 1);
1970      encodeSaoOnePart(pSaoParam, 0, 1);
1971    }
1972    m_pcEntropyCoderIf->codeSaoFlag(pSaoParam->bSaoFlag[2]); 
1973    if (pSaoParam->bSaoFlag[2])
1974    {
1975      encodeQuadTreeSplitFlag(pSaoParam, 0, 2);
1976      encodeSaoOnePart(pSaoParam, 0, 2);
1977    }
1978  }
1979}
1980#endif
1981
1982Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
1983{
1984  Int count = 0;
1985 
1986  for ( Int i = 0; i < uiSize; i++ )
1987  {
1988    count += pcCoef[i] != 0;
1989  }
1990 
1991  return count;
1992}
1993
1994/** encode quantization matrix
1995 * \param scalingList quantization matrix information
1996 */
1997Void TEncEntropy::encodeScalingList( TComScalingList* scalingList )
1998{
1999  m_pcEntropyCoderIf->codeScalingList( scalingList );
2000}
2001
2002Void TEncEntropy::encodeDFParams(TComAPS* pcAPS)
2003{
2004  m_pcEntropyCoderIf->codeDFFlag(pcAPS->getLoopFilterDisable(), "loop_filter_disable");
2005
2006  if (!pcAPS->getLoopFilterDisable())
2007  {
2008    m_pcEntropyCoderIf->codeDFSvlc(pcAPS->getLoopFilterBetaOffset(), "beta_offset_div2");
2009    m_pcEntropyCoderIf->codeDFSvlc(pcAPS->getLoopFilterTcOffset(), "tc_offset_div2");
2010  }
2011}
2012
2013//! \}
Note: See TracBrowser for help on using the repository browser.