source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibEncoder/TEnc3DAsymLUT.cpp @ 1550

Last change on this file since 1550 was 1549, checked in by seregin, 9 years ago

port rev 4732, update copyright notice to include 2016

File size: 36.3 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-2016, 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     TEnc3DAsymLUT.cpp
35    \brief    TEnc3DAsymLUT encoder class
36*/
37
38#include <cstdio>
39#include <cstdlib>
40#include <cstring>
41#include <cmath>
42#include <algorithm>
43
44#include "TEnc3DAsymLUT.h"
45
46#if CGS_3D_ASYMLUT
47TEnc3DAsymLUT::TEnc3DAsymLUT()
48{
49  m_pColorInfo = NULL;
50  m_pColorInfoC = NULL;
51  m_pEncCuboid = NULL;
52
53  m_pBestEncCuboid = NULL;
54  m_nAccuFrameBit = 0;
55  m_nAccuFrameCGSBit = 0;
56  m_nPrevFrameCGSPartNumLog2 = 0;
57  m_dTotalFrameBit = 0;
58  m_nTotalCGSBit = 0;
59  m_nPPSBit = 0;
60  m_pDsOrigPic = NULL;
61#if R0179_ENC_OPT_3DLUT_SIZE
62  m_pMaxColorInfo = NULL;
63  m_pMaxColorInfoC = NULL;
64
65 
66  // fixed m_dDistFactor
67  Double dTmpFactor[3];   
68  dTmpFactor[I_SLICE] = 1.0;
69  dTmpFactor[P_SLICE] = 4./3.;
70  dTmpFactor[B_SLICE] = 1.5; 
71  for( Int iSliceType = 0; iSliceType < 3; iSliceType++) 
72  {
73    for(Int iLayer = 0; iLayer < MAX_TLAYER; iLayer++)
74    {
75      m_dDistFactor[iSliceType][iLayer] = dTmpFactor[iSliceType]*(Double)(1<<iLayer);     
76    }
77  }
78  // initialization with approximate number of bits to code the LUT
79  m_nNumLUTBits[0][0] = 200; // 1x1x1
80  m_nNumLUTBits[1][0] = 400; // 2x1x1 
81  m_nNumLUTBits[1][1] = 1500; // 2x2x2 
82  m_nNumLUTBits[2][0] = 800; // 4x1x1
83  m_nNumLUTBits[2][1] = 3200; // 4x2x2 
84  m_nNumLUTBits[2][2] = 8500; // 4x4x4 
85  m_nNumLUTBits[3][0] = 1200; // 8x1x1
86  m_nNumLUTBits[3][1] = 4500; // 8x2x2 
87  m_nNumLUTBits[3][2] = 10000; // 8x4x4 
88  m_nNumLUTBits[3][3] = 12000; // 8x8x8
89#endif
90}
91
92Void TEnc3DAsymLUT::create( Int nMaxOctantDepth, Int nInputBitDepth, Int nInputBitDepthC, Int nOutputBitDepth, Int nOutputBitDepthC, Int nMaxYPartNumLog2 )
93{
94  if( m_pColorInfo != NULL )
95  {
96    destroy();
97  }
98
99  TCom3DAsymLUT::create( nMaxOctantDepth, nInputBitDepth, nInputBitDepthC, nOutputBitDepth, nOutputBitDepthC, nMaxYPartNumLog2, 1 << ( nInputBitDepthC - 1 ), 1 << ( nInputBitDepthC - 1 ) );
100
101  xAllocate3DArray( m_pColorInfo , xGetYSize() , xGetUSize() , xGetVSize() );
102  xAllocate3DArray( m_pColorInfoC , xGetYSize() , xGetUSize() , xGetVSize() );
103  xAllocate3DArray( m_pEncCuboid , xGetYSize() , xGetUSize() , xGetVSize() );
104  xAllocate3DArray( m_pBestEncCuboid , xGetYSize() , xGetUSize() , xGetVSize() );
105#if R0179_ENC_OPT_3DLUT_SIZE
106  xAllocate3DArray( m_pMaxColorInfo , xGetYSize() , xGetUSize() , xGetVSize() );
107  xAllocate3DArray( m_pMaxColorInfoC , xGetYSize() , xGetUSize() , xGetVSize() );
108
109  m_pEncCavlc = new TEncCavlc;
110  m_pBitstreamRedirect = new TComOutputBitstream;
111  m_pEncCavlc->setBitstream(m_pBitstreamRedirect);
112#endif
113}
114
115Void TEnc3DAsymLUT::destroy()
116{
117  xFree3DArray( m_pColorInfo );
118  xFree3DArray( m_pColorInfoC );
119  xFree3DArray( m_pEncCuboid );
120  xFree3DArray( m_pBestEncCuboid );
121#if R0179_ENC_OPT_3DLUT_SIZE
122  xFree3DArray( m_pMaxColorInfo );
123  xFree3DArray( m_pMaxColorInfoC );
124  delete m_pBitstreamRedirect;
125  delete m_pEncCavlc;
126#endif
127  TCom3DAsymLUT::destroy();
128}
129
130TEnc3DAsymLUT::~TEnc3DAsymLUT()
131{
132  if( m_dTotalFrameBit != 0 )
133  {
134    printf( "\nTotal CGS bits: %d, %.2lf%%\n\n" , m_nTotalCGSBit , m_nTotalCGSBit * 100 / m_dTotalFrameBit );
135  }
136
137  destroy();
138}
139
140Double TEnc3DAsymLUT::xDeriveVertexPerColor( Double N, Double Ys, Double Yy, Double Yu, Double Yv, Double ys, Double us, Double vs, Double yy, Double yu, Double yv, Double uu, Double uv, Double vv, Double YY,
141                                             Pel & rP0, Pel & rP1, Pel & rP3, Pel & rP7, Int nResQuantBit )
142{
143  Int nInitP0 = rP0;
144  Int nInitP1 = rP1;
145  Int nInitP3 = rP3;
146  Int nInitP7 = rP7;
147
148  const Int nOne = xGetNormCoeffOne();
149  Double dNorm = (N * yy * vv * uu - N * yy * uv * uv - N * yv * yv * uu - N * vv * yu * yu + 2 * N * yv * uv * yu - yy * vs * vs * uu + 2 * yy * vs * uv * us - yy * vv * us * us - 2 * vs * uv * yu * ys + uv * uv * ys * ys + vs * vs * yu * yu - 2 * yv * vs * us * yu + 2 * yv * vs * ys * uu - 2 * yv * uv * us * ys + 2 * vv * yu * ys * us - vv * uu * ys * ys + yv * yv * us * us);
150  if( N > 16 && dNorm != 0 )
151  {
152    Double dInitA = (-N * uu * yv * Yv + N * uu * Yy * vv - N * Yy * uv * uv + N * yv * uv * Yu - N * yu * Yu * vv + N * yu * uv * Yv + yu * us * Ys * vv - vs * ys * uv * Yu - yu * vs * us * Yv - yv * uv * us * Ys - yv * vs * us * Yu - yu * uv * vs * Ys - ys * us * uv * Yv + ys * us * Yu * vv + 2 * Yy * vs * uv * us + uu * yv * vs * Ys - uu * ys * Ys * vv + uu * vs * ys * Yv + ys * Ys * uv * uv - Yy * vv * us * us + yu * Yu * vs * vs + yv * Yv * us * us - uu * Yy * vs * vs) / dNorm;
153    Double dInitB = (N * yy * Yu * vv - N * yy * uv * Yv - N * Yu * yv * yv - N * yu * Yy * vv + N * uv * yv * Yy + N * yv * yu * Yv - yy * us * Ys * vv + yy * uv * vs * Ys - yy * Yu * vs * vs + yy * vs * us * Yv - uv * vs * ys * Yy - yv * yu * vs * Ys + yu * Yy * vs * vs + yu * ys * Ys * vv - uv * yv * ys * Ys + 2 * Yu * yv * vs * ys + us * ys * Yy * vv - vs * ys * yu * Yv + uv * ys * ys * Yv + us * Ys * yv * yv - Yu * ys * ys * vv - yv * ys * us * Yv - vs * us * yv * Yy) / dNorm;
154    Double dInitC = -(-N * yy * Yv * uu + N * yy * uv * Yu - N * yv * yu * Yu - N * uv * yu * Yy + N * Yv * yu * yu + N * yv * Yy * uu - yy * uv * us * Ys + yy * Yv * us * us + yy * vs * Ys * uu - yy * vs * us * Yu + yv * ys * us * Yu - vs * Ys * yu * yu - yv * ys * Ys * uu + vs * us * yu * Yy + vs * ys * yu * Yu - uv * Yu * ys * ys + Yv * uu * ys * ys - yv * Yy * us * us - 2 * Yv * yu * ys * us - vs * ys * Yy * uu + uv * us * ys * Yy + uv * yu * ys * Ys + yv * yu * us * Ys) / dNorm;
155    nInitP0 = ( Int )( dInitA * nOne + 0.5 ) >> nResQuantBit << nResQuantBit;
156    nInitP1 = ( Int )( dInitB * nOne + 0.5 ) >> nResQuantBit << nResQuantBit;
157    nInitP3 = ( Int )( dInitC * nOne + 0.5 ) >> nResQuantBit << nResQuantBit;
158  }
159
160  Int nMin = - ( 1 << ( m_nLUTBitDepth - 1 ) );
161  Int nMax = - nMin - ( 1 << nResQuantBit  );
162  Int nMask = ( 1 << nResQuantBit ) - 1;
163
164  Double dMinError = MAX_DOUBLE;
165  Int nTestRange = 2;
166  Int nStepSize = 1 << nResQuantBit;
167  for( Int i = - nTestRange ; i <= nTestRange ; i++ )
168  {
169    for( Int j = - nTestRange ; j <= nTestRange ; j++ )
170    {
171      for( Int k = - nTestRange ; k <= nTestRange ; k++ )
172      {
173        Int nTestP0 = Clip3( nMin , nMax , nInitP0 + i * nStepSize );
174        Int nTestP1 = Clip3( nMin , nMax , nInitP1 + j * nStepSize );
175        Int nTestP3 = Clip3( nMin , nMax , nInitP3 + k * nStepSize );
176        Double a = 1.0 * nTestP0 / nOne;
177        Double b = 1.0 * nTestP1 / nOne;
178        Double c = 1.0 * nTestP3 / nOne;
179        Double d = ( Ys - a * ys - b * us - c * vs ) / N;
180        nInitP7 = ( ( Int )d ) >> nResQuantBit << nResQuantBit;
181        for( Int m = 0 ; m < 2 ; m++ )
182        {
183          Int nTestP7 = Clip3( nMin , nMax , nInitP7 + m * nStepSize );
184          Double dError = xCalEstDist( N , Ys , Yy , Yu , Yv , ys , us , vs , yy , yu , yv , uu , uv , vv , YY , a , b , c , nTestP7 );
185          if( dError < dMinError )
186          {
187            dMinError = dError;
188            rP0 = ( Pel )nTestP0;
189            rP1 = ( Pel )nTestP1;
190            rP3 = ( Pel )nTestP3;
191            rP7 = ( Pel )nTestP7;
192          }
193        }
194      }
195    }
196  }
197  assert( !( rP0 & nMask ) && !( rP1 & nMask ) && !( rP3 & nMask ) && !( rP7 & nMask ) );
198
199  return( dMinError );
200}
201
202Double TEnc3DAsymLUT::estimateDistWithCur3DAsymLUT( TComPic * pCurPic, UInt refLayerIdc )
203{
204  xCollectData( pCurPic , refLayerIdc );
205
206  Double dErrorLuma = 0 , dErrorChroma = 0;
207  Int nYSize = 1 << ( getCurOctantDepth() + getCurYPartNumLog2() );
208  Int nUVSize = 1 << getCurOctantDepth();
209  for( Int yIdx = 0 ; yIdx < nYSize ; yIdx++ )
210  {
211    for( Int uIdx = 0 ; uIdx < nUVSize ; uIdx++ )
212    {
213      for( Int vIdx = 0 ; vIdx < nUVSize ; vIdx++ )
214      {
215        SColorInfo & rCuboidColorInfo = m_pColorInfo[yIdx][uIdx][vIdx];
216        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[yIdx][uIdx][vIdx];
217        SCuboid & rCuboid = xGetCuboid( yIdx , uIdx , vIdx );
218        if( rCuboidColorInfo.N > 0 )
219        {
220#if SCALABLE_REXT
221          dErrorLuma += xCalEstPelDist( rCuboidColorInfo.N , rCuboidColorInfo.Ys , rCuboidColorInfo.Yy , rCuboidColorInfo.Yu , rCuboidColorInfo.Yv , rCuboidColorInfo.ys , rCuboidColorInfo.us , rCuboidColorInfo.vs , rCuboidColorInfo.yy , rCuboidColorInfo.yu , rCuboidColorInfo.yv , rCuboidColorInfo.uu , rCuboidColorInfo.uv , rCuboidColorInfo.vv , rCuboidColorInfo.YY ,
222            rCuboid.P[0].Y , rCuboid.P[1].Y , rCuboid.P[2].Y , rCuboid.P[3].Y );
223#else
224          dErrorLuma += xCalEstDist( rCuboidColorInfo.N , rCuboidColorInfo.Ys , rCuboidColorInfo.Yy , rCuboidColorInfo.Yu , rCuboidColorInfo.Yv , rCuboidColorInfo.ys , rCuboidColorInfo.us , rCuboidColorInfo.vs , rCuboidColorInfo.yy , rCuboidColorInfo.yu , rCuboidColorInfo.yv , rCuboidColorInfo.uu , rCuboidColorInfo.uv , rCuboidColorInfo.vv , rCuboidColorInfo.YY ,
225            rCuboid.P[0].Y , rCuboid.P[1].Y , rCuboid.P[2].Y , rCuboid.P[3].Y );
226#endif
227        }
228        if( rCuboidColorInfoC.N > 0 )
229        {
230#if SCALABLE_REXT
231          dErrorChroma += xCalEstPelDist( rCuboidColorInfoC.N , rCuboidColorInfoC.Us , rCuboidColorInfoC.Uy , rCuboidColorInfoC.Uu , rCuboidColorInfoC.Uv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.UU ,
232            rCuboid.P[0].U , rCuboid.P[1].U , rCuboid.P[2].U , rCuboid.P[3].U );
233          dErrorChroma += xCalEstPelDist( rCuboidColorInfoC.N , rCuboidColorInfoC.Vs , rCuboidColorInfoC.Vy , rCuboidColorInfoC.Vu , rCuboidColorInfoC.Vv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.VV ,
234            rCuboid.P[0].V , rCuboid.P[1].V , rCuboid.P[2].V , rCuboid.P[3].V );
235#else
236          dErrorChroma += xCalEstDist( rCuboidColorInfoC.N , rCuboidColorInfoC.Us , rCuboidColorInfoC.Uy , rCuboidColorInfoC.Uu , rCuboidColorInfoC.Uv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.UU ,
237            rCuboid.P[0].U , rCuboid.P[1].U , rCuboid.P[2].U , rCuboid.P[3].U );
238          dErrorChroma += xCalEstDist( rCuboidColorInfoC.N , rCuboidColorInfoC.Vs , rCuboidColorInfoC.Vy , rCuboidColorInfoC.Vu , rCuboidColorInfoC.Vv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.VV ,
239            rCuboid.P[0].V , rCuboid.P[1].V , rCuboid.P[2].V , rCuboid.P[3].V );
240#endif
241        }
242      }
243    }
244  }
245
246  return( dErrorLuma + dErrorChroma);
247}
248
249#if R0179_ENC_OPT_3DLUT_SIZE
250Double TEnc3DAsymLUT::derive3DAsymLUT( TComSlice * pSlice, TComPic * pCurPic, UInt refLayerIdc, TEncCfg * pCfg, Bool bSignalPPS, Bool bElRapSliceTypeB, Double dFrameLambda )
251{
252  m_nLUTBitDepth = pCfg->getCGSLUTBit();
253
254  Int nBestAdaptCThresholdU = 1 << ( getInputBitDepthC() - 1 );
255  Int nBestAdaptCThresholdV = 1 << ( getInputBitDepthC() - 1 );
256  Int nAdaptCThresholdU, nAdaptCThresholdV;
257
258  Int nTmpLutBits[MAX_Y_SIZE][MAX_C_SIZE] ;
259  memset(nTmpLutBits, 0, sizeof(nTmpLutBits)); 
260
261  SLUTSize sMaxLutSize; 
262
263  // collect stats for the most partitions
264  Int nCurYPartNumLog2 = 0 , nCurOctantDepth = 0; 
265  Int nMaxPartNumLog2 = xGetMaxPartNumLog2();
266
267  xMapPartNum2DepthYPart( nMaxPartNumLog2 , nCurOctantDepth , nCurYPartNumLog2 ); 
268  xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
269  xCollectData( pCurPic , refLayerIdc );
270  xCopyColorInfo(m_pMaxColorInfo, m_pColorInfo, m_pMaxColorInfoC, m_pColorInfoC); 
271 
272  sMaxLutSize.iCPartNumLog2 = nCurOctantDepth; 
273  sMaxLutSize.iYPartNumLog2 = nCurOctantDepth + nCurYPartNumLog2; 
274
275  m_pBitstreamRedirect->clear();
276
277  // find the best partition based on RD cost
278  Int i; 
279  Double dMinCost, dCurCost;
280
281  Int iBestLUTSizeIdx = 0;   
282  Int nBestResQuanBit = 0;
283  Double dCurError, dMinError; 
284  Int iNumBitsCurSize; 
285  Int iNumBitsCurSizeSave = m_pEncCavlc->getNumberOfWrittenBits(); 
286  Double dDistFactor = getDistFactor(pSlice->getSliceType(), pSlice->getDepth());
287
288  // check all LUT sizes
289  xGetAllLutSizes(pSlice); 
290  if (m_nTotalLutSizes == 0) // return if no valid size is found, LUT will not be updated
291  {
292    nCurOctantDepth = sMaxLutSize.iCPartNumLog2;
293    nCurYPartNumLog2 = sMaxLutSize.iYPartNumLog2-nCurOctantDepth; 
294    xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
295    return MAX_DOUBLE; 
296  }
297
298  dMinCost = MAX_DOUBLE; dMinError = MAX_DOUBLE;
299  for (i = 0; i < m_nTotalLutSizes; i++)
300  {
301    // add up the stats
302    nCurOctantDepth = m_sLutSizes[i].iCPartNumLog2;
303    nCurYPartNumLog2 = m_sLutSizes[i].iYPartNumLog2-nCurOctantDepth; 
304    xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
305    xConsolidateData( &m_sLutSizes[i], &sMaxLutSize );
306 
307    dCurError = xDeriveVertexes(nBestResQuanBit, m_pEncCuboid);
308
309    setResQuantBit( nBestResQuanBit );
310    xSaveCuboids( m_pEncCuboid ); 
311    m_pEncCavlc->xCode3DAsymLUT( this ); 
312    iNumBitsCurSize = m_pEncCavlc->getNumberOfWrittenBits();
313    dCurCost = dCurError/dDistFactor + dFrameLambda*(Double)(iNumBitsCurSize-iNumBitsCurSizeSave); 
314    nTmpLutBits[m_sLutSizes[i].iYPartNumLog2][m_sLutSizes[i].iCPartNumLog2] = iNumBitsCurSize-iNumBitsCurSizeSave; // store LUT size
315    iNumBitsCurSizeSave = iNumBitsCurSize;
316    if(dCurCost < dMinCost )
317    {
318      SCuboid *** tmp = m_pBestEncCuboid;
319      m_pBestEncCuboid = m_pEncCuboid;
320      m_pEncCuboid = tmp;
321      dMinCost = dCurCost; 
322      dMinError = dCurError;
323      iBestLUTSizeIdx = i; 
324    }
325  }
326
327  nCurOctantDepth = m_sLutSizes[iBestLUTSizeIdx].iCPartNumLog2;
328  nCurYPartNumLog2 = m_sLutSizes[iBestLUTSizeIdx].iYPartNumLog2-nCurOctantDepth; 
329
330  xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
331
332  Bool bUseNewColorInfo = false; 
333  if( pCfg->getCGSAdaptChroma() && nCurOctantDepth <= 1 ) // if the best size found so far has depth = 0 or 1, then check AdaptC U/V thresholds
334  {
335    nAdaptCThresholdU = ( Int )( m_dSumU / m_nNChroma + 0.5 );
336    nAdaptCThresholdV = ( Int )( m_dSumV / m_nNChroma + 0.5 );
337    if( !(nAdaptCThresholdU == nBestAdaptCThresholdU && nAdaptCThresholdV == nBestAdaptCThresholdV ) ) 
338    {
339      nCurOctantDepth = 1;
340      if( nCurOctantDepth + nCurYPartNumLog2 > getMaxYPartNumLog2()+getMaxOctantDepth() )
341        nCurYPartNumLog2 = getMaxYPartNumLog2()+getMaxOctantDepth()-nCurOctantDepth; 
342      xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2 , nAdaptCThresholdU , nAdaptCThresholdV );
343      xCollectData( pCurPic , refLayerIdc );
344
345      dCurError = xDeriveVertexes( nBestResQuanBit , m_pEncCuboid ) ;
346      setResQuantBit( nBestResQuanBit );
347      xSaveCuboids( m_pEncCuboid ); 
348      m_pEncCavlc->xCode3DAsymLUT( this ); 
349      iNumBitsCurSize = m_pEncCavlc->getNumberOfWrittenBits();
350      dCurCost = dCurError/dDistFactor + dFrameLambda*(Double)(iNumBitsCurSize-iNumBitsCurSizeSave); 
351      iNumBitsCurSizeSave = iNumBitsCurSize;
352      if(dCurCost < dMinCost )
353      {
354        SCuboid *** tmp = m_pBestEncCuboid;
355        m_pBestEncCuboid = m_pEncCuboid;
356        m_pEncCuboid = tmp;
357        dMinCost = dCurCost; 
358        dMinError = dCurError;
359        nBestAdaptCThresholdU = nAdaptCThresholdU;
360        nBestAdaptCThresholdV = nAdaptCThresholdV;
361        bUseNewColorInfo = true; 
362      }
363    }
364  }
365
366  xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
367
368  // check res_quant_bits only for the best table size and best U/V threshold
369  if( !bUseNewColorInfo )
370  {
371    xConsolidateData( &m_sLutSizes[iBestLUTSizeIdx], &sMaxLutSize );
372  }
373
374  //    xCollectData( pCurPic , refLayerIdc );
375  for( Int nResQuanBit = 1 ; nResQuanBit < 4 ; nResQuanBit++ )
376  {
377    dCurError = xDeriveVertexes( nResQuanBit , m_pEncCuboid );
378
379    setResQuantBit( nResQuanBit );
380    xSaveCuboids( m_pEncCuboid ); 
381    m_pEncCavlc->xCode3DAsymLUT( this ); 
382    iNumBitsCurSize = m_pEncCavlc->getNumberOfWrittenBits();
383    dCurCost = dCurError/dDistFactor + dFrameLambda*(Double)(iNumBitsCurSize-iNumBitsCurSizeSave);   
384
385    iNumBitsCurSizeSave = iNumBitsCurSize;
386    if(dCurCost < dMinCost)
387    {
388      nBestResQuanBit = nResQuanBit;
389      SCuboid *** tmp = m_pBestEncCuboid;
390      m_pBestEncCuboid = m_pEncCuboid;
391      m_pEncCuboid = tmp;
392      dMinCost = dCurCost; 
393      dMinError = dCurError;
394    }
395    else
396    {
397      break;
398    }
399  }
400   
401  setResQuantBit( nBestResQuanBit );
402  xSaveCuboids( m_pBestEncCuboid );
403
404  // update LUT size stats
405  for(Int iLutSizeY = 0; iLutSizeY < MAX_Y_SIZE; iLutSizeY++)
406  {
407    for(Int iLutSizeC = 0; iLutSizeC < MAX_C_SIZE; iLutSizeC++) 
408    {
409      if(nTmpLutBits[iLutSizeY][iLutSizeC] != 0) 
410        m_nNumLUTBits[iLutSizeY][iLutSizeC] =  (m_nNumLUTBits[iLutSizeY][iLutSizeC] + nTmpLutBits[iLutSizeY][iLutSizeC]*3+2)>>2; // update with new stats
411    }
412  }
413
414  // return cost rather than error
415  return( dMinCost );
416}
417#endif
418
419Double TEnc3DAsymLUT::derive3DAsymLUT( TComSlice * pSlice, TComPic * pCurPic, UInt refLayerIdc, TEncCfg * pCfg, Bool bSignalPPS, Bool bElRapSliceTypeB )
420{
421  m_nLUTBitDepth = pCfg->getCGSLUTBit();
422  Int nCurYPartNumLog2 = 0 , nCurOctantDepth = 0; 
423  xDerivePartNumLog2( pSlice , pCfg , nCurOctantDepth , nCurYPartNumLog2 , bSignalPPS , bElRapSliceTypeB );
424
425  Int nBestResQuanBit = 0;
426  Int nBestAdaptCThresholdU = 1 << ( getInputBitDepthC() - 1 );
427  Int nBestAdaptCThresholdV = 1 << ( getInputBitDepthC() - 1 );
428  Int nBestOctantDepth = nCurOctantDepth;
429  Int nBestYPartNumLog2 = nCurYPartNumLog2;
430  Int nTargetLoop = 1 + ( pCfg->getCGSAdaptChroma() && ( nCurOctantDepth == 1 || ( nCurOctantDepth * 3 + nCurYPartNumLog2 ) >= 5 ) );
431  Double dMinError = MAX_DOUBLE;
432  for( Int nLoop = 0 ; nLoop < nTargetLoop ; nLoop++ )
433  {
434    Int nAdaptCThresholdU = 1 << ( getInputBitDepthC() - 1 );
435    Int nAdaptCThresholdV = 1 << ( getInputBitDepthC() - 1 );
436    if( nLoop > 0 )
437    {
438      nAdaptCThresholdU = ( Int )( m_dSumU / m_nNChroma + 0.5 );
439      nAdaptCThresholdV = ( Int )( m_dSumV / m_nNChroma + 0.5 );
440      if( nCurOctantDepth > 1 )
441      {
442        nCurOctantDepth = 1;
443        nCurYPartNumLog2 = 2;
444      }
445      if( nAdaptCThresholdU == nBestAdaptCThresholdU && nAdaptCThresholdV == nBestAdaptCThresholdV
446        && nCurOctantDepth == nBestOctantDepth && nCurYPartNumLog2 == nBestYPartNumLog2 )
447        break;
448    }
449
450    xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2 , nAdaptCThresholdU , nAdaptCThresholdV );
451    xCollectData( pCurPic , refLayerIdc );
452    for( Int nResQuanBit = 0 ; nResQuanBit < 4 ; nResQuanBit++ )
453    {
454      Double dError = xDeriveVertexes( nResQuanBit , m_pEncCuboid ) / ( 1 + ( nResQuanBit > 0 ) * 0.001 * ( pSlice->getDepth() + 1 ) );
455      if( dError <= dMinError )
456      {
457        nBestResQuanBit = nResQuanBit;
458        nBestAdaptCThresholdU = nAdaptCThresholdU;
459        nBestAdaptCThresholdV = nAdaptCThresholdV;
460        nBestOctantDepth = nCurOctantDepth;
461        nBestYPartNumLog2 = nCurYPartNumLog2;
462        SCuboid *** tmp = m_pBestEncCuboid;
463        m_pBestEncCuboid = m_pEncCuboid;
464        m_pEncCuboid = tmp;
465        dMinError = dError;
466      }
467      else
468      {
469        break;
470      }
471    }
472  }
473
474  setResQuantBit( nBestResQuanBit );
475  xUpdatePartitioning( nBestOctantDepth, nBestYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV );
476
477  xSaveCuboids( m_pBestEncCuboid );
478  return( dMinError );
479}
480
481Double TEnc3DAsymLUT::xDeriveVertexes( Int nResQuanBit, SCuboid *** pCurCuboid )
482{
483  Double dErrorLuma = 0 , dErrorChroma = 0;
484  Int nYSize = 1 << ( getCurOctantDepth() + getCurYPartNumLog2() );
485  Int nUVSize = 1 << getCurOctantDepth();
486
487  for( Int yIdx = 0 ; yIdx < nYSize ; yIdx++ )
488  {
489    for( Int uIdx = 0 ; uIdx < nUVSize ; uIdx++ )
490    {
491      for( Int vIdx = 0 ; vIdx < nUVSize ; vIdx++ )
492      {
493        SColorInfo & rCuboidColorInfo = m_pColorInfo[yIdx][uIdx][vIdx];
494        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[yIdx][uIdx][vIdx];
495        SCuboid & rCuboid = pCurCuboid[yIdx][uIdx][vIdx];
496
497        for( Int idxVertex = 0 ; idxVertex < 4 ; idxVertex++ )
498        {
499          rCuboid.P[idxVertex] = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , idxVertex , pCurCuboid );
500        }
501
502        if( rCuboidColorInfo.N > 0 )
503        {
504          dErrorLuma += xDeriveVertexPerColor( rCuboidColorInfo.N , rCuboidColorInfo.Ys , rCuboidColorInfo.Yy , rCuboidColorInfo.Yu , rCuboidColorInfo.Yv , rCuboidColorInfo.ys , rCuboidColorInfo.us , rCuboidColorInfo.vs , rCuboidColorInfo.yy , rCuboidColorInfo.yu , rCuboidColorInfo.yv , rCuboidColorInfo.uu , rCuboidColorInfo.uv , rCuboidColorInfo.vv , rCuboidColorInfo.YY ,
505            rCuboid.P[0].Y , rCuboid.P[1].Y , rCuboid.P[2].Y , rCuboid.P[3].Y , nResQuanBit );
506        }
507
508        if( rCuboidColorInfoC.N > 0 )
509        {
510          dErrorChroma += xDeriveVertexPerColor( rCuboidColorInfoC.N , rCuboidColorInfoC.Us , rCuboidColorInfoC.Uy , rCuboidColorInfoC.Uu , rCuboidColorInfoC.Uv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.UU ,
511            rCuboid.P[0].U , rCuboid.P[1].U , rCuboid.P[2].U , rCuboid.P[3].U , nResQuanBit );
512
513          dErrorChroma += xDeriveVertexPerColor( rCuboidColorInfoC.N , rCuboidColorInfoC.Vs , rCuboidColorInfoC.Vy , rCuboidColorInfoC.Vu , rCuboidColorInfoC.Vv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.VV ,
514            rCuboid.P[0].V , rCuboid.P[1].V , rCuboid.P[2].V , rCuboid.P[3].V , nResQuanBit );
515        }
516
517        if( nResQuanBit > 0 )
518        {
519          // check quantization
520          for( Int idxVertex = 0 ; idxVertex < 4 ; idxVertex++ )
521          {
522            SYUVP sPred = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , idxVertex , pCurCuboid );
523            assert( ( ( rCuboid.P[idxVertex].Y - sPred.Y ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].Y - sPred.Y );
524            assert( ( ( rCuboid.P[idxVertex].U - sPred.U ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].U - sPred.U );
525            assert( ( ( rCuboid.P[idxVertex].V - sPred.V ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].V - sPred.V );
526          }
527        }
528      }
529    }
530  }
531
532  return( dErrorLuma + dErrorChroma );
533}
534
535Void TEnc3DAsymLUT::xCollectData( TComPic * pCurPic, UInt refLayerIdc )
536{
537  Pel * pSrcY = m_pDsOrigPic->getAddr(COMPONENT_Y);
538  Pel * pSrcU = m_pDsOrigPic->getAddr(COMPONENT_Cb);
539  Pel * pSrcV = m_pDsOrigPic->getAddr(COMPONENT_Cr);
540  Int nStrideSrcY = m_pDsOrigPic->getStride(COMPONENT_Y);
541  Int nStrideSrcC = m_pDsOrigPic->getStride(COMPONENT_Cb);
542  TComPicYuv *pRecPic = pCurPic->getSlice(pCurPic->getCurrSliceIdx())->getBaseColPic(refLayerIdc)->getPicYuvRec();
543  Pel * pIRLY = pRecPic->getAddr(COMPONENT_Y);
544  Pel * pIRLU = pRecPic->getAddr(COMPONENT_Cb);
545  Pel * pIRLV = pRecPic->getAddr(COMPONENT_Cr);
546  Int nStrideILRY = pRecPic->getStride(COMPONENT_Y);
547  Int nStrideILRC = pRecPic->getStride(COMPONENT_Cb);
548#if R0179_ENC_OPT_3DLUT_SIZE
549  xReset3DArray( m_pColorInfo  , getMaxYSize() , getMaxCSize() , getMaxCSize() );
550  xReset3DArray( m_pColorInfoC , getMaxYSize() , getMaxCSize() , getMaxCSize() );
551#else
552  xReset3DArray( m_pColorInfo , xGetYSize() , xGetUSize() , xGetVSize() );
553  xReset3DArray( m_pColorInfoC , xGetYSize() , xGetUSize() , xGetVSize() );
554#endif
555
556  //alignment padding
557  pRecPic->setBorderExtension( false );
558  pRecPic->extendPicBorder();
559
560  TComSlice * pSlice = pCurPic->getSlice(pCurPic->getCurrSliceIdx());
561  UInt refLayerId = pSlice->getVPS()->getRefLayerId(pSlice->getLayerId(), refLayerIdc);
562  Window scalEL = pSlice->getPPS()->getScaledRefLayerWindowForLayer(refLayerId); 
563  TComPicYuv *pcRecPicBL = pSlice->getBaseColPic(refLayerIdc)->getPicYuvRec();
564  // borders of down-sampled picture
565  Int leftDS =  (scalEL.getWindowLeftOffset() * pSlice->getPic()->getPosScalingFactor(refLayerIdc, 0)+(1<<15))>>16;
566  Int rightDS = pcRecPicBL->getWidth(COMPONENT_Y) - 1 + (((scalEL.getWindowRightOffset()) * pSlice->getPic()->getPosScalingFactor(refLayerIdc, 0)+(1<<15))>>16);
567  Int topDS = (((scalEL.getWindowTopOffset()) * pSlice->getPic()->getPosScalingFactor(refLayerIdc, 1)+(1<<15))>>16);
568  Int bottomDS = pcRecPicBL->getHeight(COMPONENT_Y) - 1 + (((scalEL.getWindowBottomOffset()) * pSlice->getPic()->getPosScalingFactor(refLayerIdc, 1)+(1<<15))>>16);
569  // overlapped region
570  Int left = max( 0 , leftDS );
571  Int right = min( pcRecPicBL->getWidth(COMPONENT_Y) - 1 , rightDS );
572  Int top = max( 0 , topDS );
573  Int bottom = min( pcRecPicBL->getHeight(COMPONENT_Y) - 1 , bottomDS );
574  // since we do data collection only for overlapped region, the border extension is good enough
575
576  m_dSumU = m_dSumV = 0;
577  m_nNChroma = 0;
578
579  for( Int i = top ; i <= bottom ; i++ )
580  {
581    Int iDS = i-topDS;
582    Int jDS = left-leftDS;
583    Int posSrcY = iDS * nStrideSrcY + jDS;
584    Int posIRLY = i * nStrideILRY + left;
585    Int posSrcUV = ( iDS >> 1 ) * nStrideSrcC + (jDS>>1);
586    Int posIRLUV = ( i >> 1 ) * nStrideILRC + (left>>1);
587    for( Int j = left ; j <= right ; j++ , posSrcY++ , posIRLY++ , posSrcUV += !( j & 0x01 ) , posIRLUV += !( j & 0x01 ) )
588    {
589      Int Y = pSrcY[posSrcY];
590      Int y = pIRLY[posIRLY];
591      Int U = pSrcU[posSrcUV];
592      Int u = pIRLU[posIRLUV];
593      Int V = pSrcV[posSrcUV];
594      Int v = pIRLV[posIRLUV];
595
596      // alignment
597      //filtering u, v for luma;
598      Int posIRLUVN =  posIRLUV + ((i&1)? nStrideILRC : -nStrideILRC);
599      if((j&1))
600      {
601        u = (pIRLU[posIRLUVN] + pIRLU[posIRLUVN+1] +(u + pIRLU[posIRLUV+1])*3 +4)>>3;
602        v = (pIRLV[posIRLUVN] + pIRLV[posIRLUVN+1] +(v + pIRLV[posIRLUV+1])*3 +4)>>3;
603      }
604      else
605      { 
606        u = (pIRLU[posIRLUVN] +u*3 +2)>>2;
607        v = (pIRLV[posIRLUVN] +v*3 +2)>>2;
608      }
609
610      m_dSumU += u;
611      m_dSumV += v;
612      m_nNChroma++;
613
614      SColorInfo sColorInfo;
615      SColorInfo & rCuboidColorInfo = m_pColorInfo[xGetYIdx(y)][xGetUIdx(u)][xGetVIdx(v)];
616
617      memset(&sColorInfo, 0, sizeof(SColorInfo));
618
619      sColorInfo.Ys = Y;
620      sColorInfo.ys = y;
621      sColorInfo.us = u;
622      sColorInfo.vs = v;
623      sColorInfo.Yy = Y * y;
624      sColorInfo.Yu = Y * u;
625      sColorInfo.Yv = Y * v;
626      sColorInfo.yy = y * y;
627      sColorInfo.yu = y * u;
628      sColorInfo.yv = y * v;
629      sColorInfo.uu = u * u;
630      sColorInfo.uv = u * v;
631      sColorInfo.vv = v * v;
632      sColorInfo.YY = Y * Y;
633      sColorInfo.= 1;
634
635      rCuboidColorInfo += sColorInfo;
636
637      if(!((i&1) || (j&1)))
638      {
639        // alignment
640        y =  (pIRLY[posIRLY] + pIRLY[posIRLY+nStrideILRY] + 1)>>1;
641
642        u = pIRLU[posIRLUV];
643        v = pIRLV[posIRLUV];
644
645        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[xGetYIdx(y)][xGetUIdx(u)][xGetVIdx(v)];
646
647        sColorInfo.Us = U;
648        sColorInfo.Vs = V;
649        sColorInfo.ys = y;
650        sColorInfo.us = u;
651        sColorInfo.vs = v;
652
653        sColorInfo.Uy = U * y;
654        sColorInfo.Uu = U * u;
655        sColorInfo.Uv = U * v;
656        sColorInfo.Vy = V * y;
657        sColorInfo.Vu = V * u;
658        sColorInfo.Vv = V * v;
659        sColorInfo.yy = y * y;
660        sColorInfo.yu = y * u;
661        sColorInfo.yv = y * v;
662        sColorInfo.uu = u * u;
663        sColorInfo.uv = u * v;
664        sColorInfo.vv = v * v;
665        sColorInfo.UU = U * U;
666        sColorInfo.VV = V * V;
667        sColorInfo.= 1;
668
669        rCuboidColorInfoC += sColorInfo;
670      }
671    }
672  }
673}
674
675Void TEnc3DAsymLUT::xDerivePartNumLog2( TComSlice * pSlice, TEncCfg * pcCfg, Int & rOctantDepth, Int & rYPartNumLog2, Bool bSignalPPS, Bool bElRapSliceTypeB )
676{
677  Int nPartNumLog2 = 4;
678  if( pSlice->getBaseColPic( pSlice->getInterLayerPredLayerIdc( 0 ) )->getSlice( 0 )->isIntra() )
679  {
680    nPartNumLog2 = xGetMaxPartNumLog2();
681  }
682
683  if( m_nAccuFrameBit && pSlice->getPPS()->getCGSFlag() ) 
684  {
685    Double dBitCost = 1.0 * m_nAccuFrameCGSBit / m_nAccuFrameBit;
686    nPartNumLog2 = m_nPrevFrameCGSPartNumLog2;
687
688    Double dBitCostT = 0.03;
689    if( dBitCost < dBitCostT / 6.0 )
690    {
691      nPartNumLog2++;
692    }
693    else if( dBitCost >= dBitCostT )
694    {
695      nPartNumLog2--;
696    }
697  }
698
699  nPartNumLog2 = Clip3( 0 , xGetMaxPartNumLog2()  , nPartNumLog2 );
700  xMapPartNum2DepthYPart( nPartNumLog2 , rOctantDepth , rYPartNumLog2 );
701}
702
703Void TEnc3DAsymLUT::xMapPartNum2DepthYPart( Int nPartNumLog2, Int & rOctantDepth, Int & rYPartNumLog2 )
704{
705  for( Int y = getMaxYPartNumLog2() ; y >= 0 ; y-- )
706  {
707    for( Int depth = ( nPartNumLog2 - y ) >> 1 ; depth >= 0 ; depth-- )
708    {
709      if( y + 3 * depth == nPartNumLog2 )
710      {
711        rOctantDepth = depth;
712        rYPartNumLog2 = y;
713        return;
714      }
715    }
716  }
717  rOctantDepth = min( getMaxOctantDepth() , nPartNumLog2 / 3 );
718  rYPartNumLog2 = min( getMaxYPartNumLog2() , nPartNumLog2 - 3 * rOctantDepth );
719}
720
721Void TEnc3DAsymLUT::updatePicCGSBits( TComSlice * pcSlice, Int nPPSBit )
722{
723  for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
724  {
725    UInt refLayerIdc = pcSlice->getInterLayerPredLayerIdc(i);
726    m_nAccuFrameBit += pcSlice->getPic()->getFrameBit() + pcSlice->getBaseColPic(refLayerIdc)->getFrameBit();
727    m_dTotalFrameBit += pcSlice->getPic()->getFrameBit() + pcSlice->getBaseColPic(refLayerIdc)->getFrameBit();
728  }
729
730  m_nAccuFrameCGSBit += nPPSBit;
731  m_nTotalCGSBit += nPPSBit;
732  m_nPrevFrameCGSPartNumLog2 = getCurOctantDepth() * 3 + getCurYPartNumLog2();
733
734#if R0179_ENC_OPT_3DLUT_SIZE
735  Int nCurELFrameBit = pcSlice->getPic()->getFrameBit();
736  const Int nSliceType = pcSlice->getSliceType();
737  const Int nSliceTempLevel = pcSlice->getDepth();
738  m_nPrevELFrameBit[nSliceType][nSliceTempLevel] = m_nPrevELFrameBit[nSliceType][nSliceTempLevel] == 0 ? nCurELFrameBit:((m_nPrevELFrameBit[nSliceType][nSliceTempLevel]+nCurELFrameBit)>>1);
739#endif
740}
741
742#if R0179_ENC_OPT_3DLUT_SIZE
743
744Void TEnc3DAsymLUT::xGetAllLutSizes(TComSlice *pSlice)
745{
746  Int iMaxYPartNumLog2, iMaxCPartNumLog2; 
747  Int iCurYPartNumLog2, iCurCPartNumLog2; 
748  Int iMaxAddYPartNumLog2; 
749  Int iNumELFrameBits = m_nPrevELFrameBit[pSlice->getSliceType()][pSlice->getDepth()];
750
751  xMapPartNum2DepthYPart( xGetMaxPartNumLog2(), iMaxCPartNumLog2, iMaxYPartNumLog2 );
752  iMaxAddYPartNumLog2 = iMaxYPartNumLog2; 
753  iMaxYPartNumLog2 += iMaxCPartNumLog2; 
754
755  //m_sLutSizes[0].iYPartNumLog2 = iMaxYPartNumLog2;
756  //m_sLutSizes[0].iCPartNumLog2 = iMaxCPartNumLog2;
757  m_nTotalLutSizes = 0; 
758
759
760  for(iCurYPartNumLog2 = iMaxYPartNumLog2; iCurYPartNumLog2 >= 0; iCurYPartNumLog2--) 
761  {
762    for(iCurCPartNumLog2 = iMaxCPartNumLog2; iCurCPartNumLog2 >= 0; iCurCPartNumLog2--) 
763    {
764       // try more sizes
765      if(iCurCPartNumLog2 <= iCurYPartNumLog2  && 
766         (m_nNumLUTBits[iCurYPartNumLog2][iCurCPartNumLog2] < (iNumELFrameBits>>1)) && 
767         m_nTotalLutSizes < MAX_NUM_LUT_SIZES)
768      {
769        m_sLutSizes[m_nTotalLutSizes].iYPartNumLog2 = iCurYPartNumLog2; 
770        m_sLutSizes[m_nTotalLutSizes].iCPartNumLog2 = iCurCPartNumLog2; 
771        m_nTotalLutSizes ++; 
772      }
773    }
774  }
775
776}
777
778Void TEnc3DAsymLUT::xCopyColorInfo( SColorInfo *** dst, SColorInfo *** src,  SColorInfo *** dstC, SColorInfo *** srcC )
779{
780  Int yIdx, uIdx, vIdx; 
781
782  // copy from pColorInfo to pMaxColorInfo
783  for(yIdx = 0; yIdx < xGetYSize(); yIdx++)
784  {
785    for(uIdx = 0; uIdx < xGetUSize(); uIdx++)
786    {
787      for(vIdx = 0; vIdx < xGetVSize(); vIdx++)
788      {
789        dst [yIdx][uIdx][vIdx] = src [yIdx][uIdx][vIdx];
790        dstC[yIdx][uIdx][vIdx] = srcC[yIdx][uIdx][vIdx];
791      }
792    }
793  }
794}
795
796Void TEnc3DAsymLUT::xAddColorInfo( Int yIdx, Int uIdx, Int vIdx, Int iYDiffLog2, Int iCDiffLog2 )
797{
798  SColorInfo & rCuboidColorInfo  = m_pColorInfo [yIdx][uIdx][vIdx];
799  SColorInfo & rCuboidColorInfoC = m_pColorInfoC[yIdx][uIdx][vIdx];
800 
801  for( Int i = 0; i < (1<<iYDiffLog2); i++)
802  {
803    for (Int j = 0; j < (1<<iCDiffLog2); j++)
804    {
805      for(Int k = 0; k < (1<<iCDiffLog2); k++)
806      {
807        rCuboidColorInfo  += m_pMaxColorInfo [(yIdx<<iYDiffLog2)+i][(uIdx<<iCDiffLog2)+j][(vIdx<<iCDiffLog2)+k];
808        rCuboidColorInfoC += m_pMaxColorInfoC[(yIdx<<iYDiffLog2)+i][(uIdx<<iCDiffLog2)+j][(vIdx<<iCDiffLog2)+k];
809      }
810    }
811  }
812}
813
814Void TEnc3DAsymLUT::xConsolidateData( SLUTSize *pCurLUTSize, SLUTSize *pMaxLUTSize )
815{
816  Int yIdx, uIdx, vIdx; 
817  Int iYDiffLog2, iCDiffLog2;
818  Int nYSize = 1<< pMaxLUTSize->iYPartNumLog2;
819  Int nCSize = 1<< pMaxLUTSize->iCPartNumLog2;
820
821  iYDiffLog2 = pMaxLUTSize->iYPartNumLog2-pCurLUTSize->iYPartNumLog2;
822  iCDiffLog2 = pMaxLUTSize->iCPartNumLog2-pCurLUTSize->iCPartNumLog2;
823
824  //assert(pMaxLUTSize->iCPartNumLog2 >= pCurLUTSize->iCPartNumLog2 && pMaxLUTSize->iYPartNumLog2 >= pCurLUTSize->iYPartNumLog2);
825  if (iYDiffLog2 == 0 && iCDiffLog2 == 0) // shouldn't have to do anything
826  {
827    xCopyColorInfo(m_pColorInfo, m_pMaxColorInfo, m_pColorInfoC, m_pMaxColorInfoC);
828    return; 
829  }
830
831  xReset3DArray( m_pColorInfo,   1<<pMaxLUTSize->iYPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2 );
832  xReset3DArray( m_pColorInfoC,  1<<pMaxLUTSize->iYPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2 );
833
834  for(yIdx = 0; yIdx < nYSize; yIdx++)
835  {
836    for(uIdx = 0; uIdx < nCSize; uIdx++)
837    {
838      for(vIdx = 0; vIdx < nCSize; vIdx++)
839      {
840        const SColorInfo & rCuboidSrc   = m_pMaxColorInfo [yIdx][uIdx][vIdx];
841        const SColorInfo & rCuboidSrcC  = m_pMaxColorInfoC[yIdx][uIdx][vIdx];
842       
843        Int yIdx2, uIdx2, vIdx2; 
844        yIdx2 = yIdx>>iYDiffLog2; 
845        uIdx2 = uIdx>>iCDiffLog2;
846        vIdx2 = vIdx>>iCDiffLog2; 
847
848        m_pColorInfo [yIdx2][uIdx2][vIdx2] += rCuboidSrc;
849        m_pColorInfoC[yIdx2][uIdx2][vIdx2] += rCuboidSrcC;
850      }
851    }
852  }
853}
854
855Void TEnc3DAsymLUT::update3DAsymLUTParam( TEnc3DAsymLUT * pSrc )
856{
857  assert( pSrc->getMaxOctantDepth() == getMaxOctantDepth() && pSrc->getMaxYPartNumLog2() == getMaxYPartNumLog2() );
858  xUpdatePartitioning( pSrc->getCurOctantDepth(), pSrc->getCurYPartNumLog2(), pSrc->getAdaptChromaThresholdU(), pSrc->getAdaptChromaThresholdV() );
859  setResQuantBit( pSrc->getResQuantBit() );
860}
861#endif
862#endif
Note: See TracBrowser for help on using the repository browser.