source: 3DVCSoftware/branches/HTM-4.0.1-VSP-dev0/source/Lib/TLibEncoder/TEncEntropy.cpp @ 166

Last change on this file since 166 was 166, checked in by mitsubishi-htm, 12 years ago

Initial integration of VSP into HTM 4.0.1. The version used for JCT3V-B0102 at Shanghai meeting.

  • VC9 project/solution files updated. Other Visual C++ project/solution files are not updated.
  • Linux make file updated.

TODO

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