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

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