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

Last change on this file since 1323 was 1297, checked in by seregin, 9 years ago

port rev 4329 and update copyright

File size: 34.8 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-2015, 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 bit: %d, %.2lf%%" , m_nTotalCGSBit , m_nTotalCGSBit * 100 / m_dTotalFrameBit );
135  }
136
137  destroy();
138}
139
140Double TEnc3DAsymLUT::xxDeriveVertexPerColor( 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 = xxCalEstDist( 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  xxCollectData( 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          dErrorLuma += xxCalEstDist( 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 ,
221            rCuboid.P[0].Y , rCuboid.P[1].Y , rCuboid.P[2].Y , rCuboid.P[3].Y );
222        }
223        if( rCuboidColorInfoC.N > 0 )
224        {
225          dErrorChroma += xxCalEstDist( 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 ,
226            rCuboid.P[0].U , rCuboid.P[1].U , rCuboid.P[2].U , rCuboid.P[3].U );
227          dErrorChroma += xxCalEstDist( 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 ,
228            rCuboid.P[0].V , rCuboid.P[1].V , rCuboid.P[2].V , rCuboid.P[3].V );
229        }
230      }
231    }
232  }
233
234  return( dErrorLuma + dErrorChroma);
235}
236
237#if R0179_ENC_OPT_3DLUT_SIZE
238Double TEnc3DAsymLUT::derive3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS , Bool bElRapSliceTypeB, Double dFrameLambda )
239{
240  m_nLUTBitDepth = pCfg->getCGSLUTBit();
241
242  Int nBestAdaptCThresholdU = 1 << ( getInputBitDepthC() - 1 );
243  Int nBestAdaptCThresholdV = 1 << ( getInputBitDepthC() - 1 );
244  Int nAdaptCThresholdU, nAdaptCThresholdV;
245
246  Int nTmpLutBits[MAX_Y_SIZE][MAX_C_SIZE] ;
247  memset(nTmpLutBits, 0, sizeof(nTmpLutBits)); 
248
249  SLUTSize sMaxLutSize; 
250
251  // collect stats for the most partitions
252  Int nCurYPartNumLog2 = 0 , nCurOctantDepth = 0; 
253  Int nMaxPartNumLog2 = xGetMaxPartNumLog2();
254
255  xxMapPartNum2DepthYPart( nMaxPartNumLog2 , nCurOctantDepth , nCurYPartNumLog2 ); 
256  xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
257  xxCollectData( pCurPic , refLayerIdc );
258  xxCopyColorInfo(m_pMaxColorInfo, m_pColorInfo, m_pMaxColorInfoC, m_pColorInfoC); 
259 
260  sMaxLutSize.iCPartNumLog2 = nCurOctantDepth; 
261  sMaxLutSize.iYPartNumLog2 = nCurOctantDepth + nCurYPartNumLog2; 
262
263  m_pBitstreamRedirect->clear();
264
265  // find the best partition based on RD cost
266  Int i; 
267  Double dMinCost, dCurCost;
268
269  Int iBestLUTSizeIdx = 0;   
270  Int nBestResQuanBit = 0;
271  Double dCurError, dMinError; 
272  Int iNumBitsCurSize; 
273  Int iNumBitsCurSizeSave = m_pEncCavlc->getNumberOfWrittenBits(); 
274  Double dDistFactor = getDistFactor(pSlice->getSliceType(), pSlice->getDepth());
275
276  // check all LUT sizes
277  xxGetAllLutSizes(pSlice); 
278  if (m_nTotalLutSizes == 0) // return if no valid size is found, LUT will not be updated
279  {
280    nCurOctantDepth = sMaxLutSize.iCPartNumLog2;
281    nCurYPartNumLog2 = sMaxLutSize.iYPartNumLog2-nCurOctantDepth; 
282    xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
283    return MAX_DOUBLE; 
284  }
285
286  dMinCost = MAX_DOUBLE; dMinError = MAX_DOUBLE;
287  for (i = 0; i < m_nTotalLutSizes; i++)
288  {
289    // add up the stats
290    nCurOctantDepth = m_sLutSizes[i].iCPartNumLog2;
291    nCurYPartNumLog2 = m_sLutSizes[i].iYPartNumLog2-nCurOctantDepth; 
292    xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
293    xxConsolidateData( &m_sLutSizes[i], &sMaxLutSize );
294 
295    dCurError = xxDeriveVertexes(nBestResQuanBit, m_pEncCuboid);
296
297    setResQuantBit( nBestResQuanBit );
298    xSaveCuboids( m_pEncCuboid ); 
299    m_pEncCavlc->xCode3DAsymLUT( this ); 
300    iNumBitsCurSize = m_pEncCavlc->getNumberOfWrittenBits();
301    dCurCost = dCurError/dDistFactor + dFrameLambda*(Double)(iNumBitsCurSize-iNumBitsCurSizeSave); 
302    nTmpLutBits[m_sLutSizes[i].iYPartNumLog2][m_sLutSizes[i].iCPartNumLog2] = iNumBitsCurSize-iNumBitsCurSizeSave; // store LUT size
303    iNumBitsCurSizeSave = iNumBitsCurSize;
304    if(dCurCost < dMinCost )
305    {
306      SCuboid *** tmp = m_pBestEncCuboid;
307      m_pBestEncCuboid = m_pEncCuboid;
308      m_pEncCuboid = tmp;
309      dMinCost = dCurCost; 
310      dMinError = dCurError;
311      iBestLUTSizeIdx = i; 
312    }
313  }
314
315  nCurOctantDepth = m_sLutSizes[iBestLUTSizeIdx].iCPartNumLog2;
316  nCurYPartNumLog2 = m_sLutSizes[iBestLUTSizeIdx].iYPartNumLog2-nCurOctantDepth; 
317
318  xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
319
320  Bool bUseNewColorInfo = false; 
321  if( pCfg->getCGSAdaptChroma() && nCurOctantDepth <= 1 ) // if the best size found so far has depth = 0 or 1, then check AdaptC U/V thresholds
322  {
323    nAdaptCThresholdU = ( Int )( m_dSumU / m_nNChroma + 0.5 );
324    nAdaptCThresholdV = ( Int )( m_dSumV / m_nNChroma + 0.5 );
325    if( !(nAdaptCThresholdU == nBestAdaptCThresholdU && nAdaptCThresholdV == nBestAdaptCThresholdV ) ) 
326    {
327      nCurOctantDepth = 1;
328      if( nCurOctantDepth + nCurYPartNumLog2 > getMaxYPartNumLog2()+getMaxOctantDepth() )
329        nCurYPartNumLog2 = getMaxYPartNumLog2()+getMaxOctantDepth()-nCurOctantDepth; 
330      xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2 , nAdaptCThresholdU , nAdaptCThresholdV );
331      xxCollectData( pCurPic , refLayerIdc );
332
333      dCurError = xxDeriveVertexes( nBestResQuanBit , m_pEncCuboid ) ;
334      setResQuantBit( nBestResQuanBit );
335      xSaveCuboids( m_pEncCuboid ); 
336      m_pEncCavlc->xCode3DAsymLUT( this ); 
337      iNumBitsCurSize = m_pEncCavlc->getNumberOfWrittenBits();
338      dCurCost = dCurError/dDistFactor + dFrameLambda*(Double)(iNumBitsCurSize-iNumBitsCurSizeSave); 
339      iNumBitsCurSizeSave = iNumBitsCurSize;
340      if(dCurCost < dMinCost )
341      {
342        SCuboid *** tmp = m_pBestEncCuboid;
343        m_pBestEncCuboid = m_pEncCuboid;
344        m_pEncCuboid = tmp;
345        dMinCost = dCurCost; 
346        dMinError = dCurError;
347        nBestAdaptCThresholdU = nAdaptCThresholdU;
348        nBestAdaptCThresholdV = nAdaptCThresholdV;
349        bUseNewColorInfo = true; 
350      }
351    }
352  }
353
354  xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
355
356  // check res_quant_bits only for the best table size and best U/V threshold
357  if( !bUseNewColorInfo ) 
358    xxConsolidateData( &m_sLutSizes[iBestLUTSizeIdx], &sMaxLutSize );
359
360  //    xxCollectData( pCurPic , refLayerIdc );
361  for( Int nResQuanBit = 1 ; nResQuanBit < 4 ; nResQuanBit++ )
362  {
363    dCurError = xxDeriveVertexes( nResQuanBit , m_pEncCuboid );
364
365    setResQuantBit( nResQuanBit );
366    xSaveCuboids( m_pEncCuboid ); 
367    m_pEncCavlc->xCode3DAsymLUT( this ); 
368    iNumBitsCurSize = m_pEncCavlc->getNumberOfWrittenBits();
369    dCurCost = dCurError/dDistFactor + dFrameLambda*(Double)(iNumBitsCurSize-iNumBitsCurSizeSave);   
370
371    iNumBitsCurSizeSave = iNumBitsCurSize;
372    if(dCurCost < dMinCost)
373    {
374      nBestResQuanBit = nResQuanBit;
375      SCuboid *** tmp = m_pBestEncCuboid;
376      m_pBestEncCuboid = m_pEncCuboid;
377      m_pEncCuboid = tmp;
378      dMinCost = dCurCost; 
379      dMinError = dCurError;
380    }
381    else
382    {
383      break;
384    }
385  }
386   
387  setResQuantBit( nBestResQuanBit );
388  xSaveCuboids( m_pBestEncCuboid );
389
390  // update LUT size stats
391  for(Int iLutSizeY = 0; iLutSizeY < MAX_Y_SIZE; iLutSizeY++)
392  {
393    for(Int iLutSizeC = 0; iLutSizeC < MAX_C_SIZE; iLutSizeC++) 
394    {
395      if(nTmpLutBits[iLutSizeY][iLutSizeC] != 0) 
396        m_nNumLUTBits[iLutSizeY][iLutSizeC] =  (m_nNumLUTBits[iLutSizeY][iLutSizeC] + nTmpLutBits[iLutSizeY][iLutSizeC]*3+2)>>2; // update with new stats
397    }
398  }
399
400  // return cost rather than error
401  return( dMinCost );
402}
403#endif
404
405Double TEnc3DAsymLUT::derive3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS , Bool bElRapSliceTypeB )
406{
407  m_nLUTBitDepth = pCfg->getCGSLUTBit();
408  Int nCurYPartNumLog2 = 0 , nCurOctantDepth = 0; 
409  xxDerivePartNumLog2( pSlice , pCfg , nCurOctantDepth , nCurYPartNumLog2 , bSignalPPS , bElRapSliceTypeB );
410
411  Int nBestResQuanBit = 0;
412  Int nBestAdaptCThresholdU = 1 << ( getInputBitDepthC() - 1 );
413  Int nBestAdaptCThresholdV = 1 << ( getInputBitDepthC() - 1 );
414  Int nBestOctantDepth = nCurOctantDepth;
415  Int nBestYPartNumLog2 = nCurYPartNumLog2;
416  Int nTargetLoop = 1 + ( pCfg->getCGSAdaptChroma() && ( nCurOctantDepth == 1 || ( nCurOctantDepth * 3 + nCurYPartNumLog2 ) >= 5 ) );
417  Double dMinError = MAX_DOUBLE;
418  for( Int nLoop = 0 ; nLoop < nTargetLoop ; nLoop++ )
419  {
420    Int nAdaptCThresholdU = 1 << ( getInputBitDepthC() - 1 );
421    Int nAdaptCThresholdV = 1 << ( getInputBitDepthC() - 1 );
422    if( nLoop > 0 )
423    {
424      nAdaptCThresholdU = ( Int )( m_dSumU / m_nNChroma + 0.5 );
425      nAdaptCThresholdV = ( Int )( m_dSumV / m_nNChroma + 0.5 );
426      if( nCurOctantDepth > 1 )
427      {
428        nCurOctantDepth = 1;
429        nCurYPartNumLog2 = 2;
430      }
431      if( nAdaptCThresholdU == nBestAdaptCThresholdU && nAdaptCThresholdV == nBestAdaptCThresholdV
432        && nCurOctantDepth == nBestOctantDepth && nCurYPartNumLog2 == nBestYPartNumLog2 )
433        break;
434    }
435
436    xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2 , nAdaptCThresholdU , nAdaptCThresholdV );
437    xxCollectData( pCurPic , refLayerIdc );
438    for( Int nResQuanBit = 0 ; nResQuanBit < 4 ; nResQuanBit++ )
439    {
440      Double dError = xxDeriveVertexes( nResQuanBit , m_pEncCuboid ) / ( 1 + ( nResQuanBit > 0 ) * 0.001 * ( pSlice->getDepth() + 1 ) );
441      if( dError <= dMinError )
442      {
443        nBestResQuanBit = nResQuanBit;
444        nBestAdaptCThresholdU = nAdaptCThresholdU;
445        nBestAdaptCThresholdV = nAdaptCThresholdV;
446        nBestOctantDepth = nCurOctantDepth;
447        nBestYPartNumLog2 = nCurYPartNumLog2;
448        SCuboid *** tmp = m_pBestEncCuboid;
449        m_pBestEncCuboid = m_pEncCuboid;
450        m_pEncCuboid = tmp;
451        dMinError = dError;
452      }
453      else
454      {
455        break;
456      }
457    }
458  }
459
460  setResQuantBit( nBestResQuanBit );
461  xUpdatePartitioning( nBestOctantDepth , nBestYPartNumLog2 , nBestAdaptCThresholdU , nBestAdaptCThresholdV );
462
463  xSaveCuboids( m_pBestEncCuboid );
464  return( dMinError );
465}
466
467Double TEnc3DAsymLUT::xxDeriveVertexes( Int nResQuanBit , SCuboid *** pCurCuboid )
468{
469  Double dErrorLuma = 0 , dErrorChroma = 0;
470  Int nYSize = 1 << ( getCurOctantDepth() + getCurYPartNumLog2() );
471  Int nUVSize = 1 << getCurOctantDepth();
472
473  for( Int yIdx = 0 ; yIdx < nYSize ; yIdx++ )
474  {
475    for( Int uIdx = 0 ; uIdx < nUVSize ; uIdx++ )
476    {
477      for( Int vIdx = 0 ; vIdx < nUVSize ; vIdx++ )
478      {
479        SColorInfo & rCuboidColorInfo = m_pColorInfo[yIdx][uIdx][vIdx];
480        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[yIdx][uIdx][vIdx];
481        SCuboid & rCuboid = pCurCuboid[yIdx][uIdx][vIdx];
482
483        for( Int idxVertex = 0 ; idxVertex < 4 ; idxVertex++ )
484        {
485          rCuboid.P[idxVertex] = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , idxVertex , pCurCuboid );
486        }
487
488        if( rCuboidColorInfo.N > 0 )
489        {
490          dErrorLuma += xxDeriveVertexPerColor( 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 ,
491            rCuboid.P[0].Y , rCuboid.P[1].Y , rCuboid.P[2].Y , rCuboid.P[3].Y , nResQuanBit );
492        }
493
494        if( rCuboidColorInfoC.N > 0 )
495        {
496          dErrorChroma += xxDeriveVertexPerColor( 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 ,
497            rCuboid.P[0].U , rCuboid.P[1].U , rCuboid.P[2].U , rCuboid.P[3].U , nResQuanBit );
498
499          dErrorChroma += xxDeriveVertexPerColor( 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 ,
500            rCuboid.P[0].V , rCuboid.P[1].V , rCuboid.P[2].V , rCuboid.P[3].V , nResQuanBit );
501        }
502
503        if( nResQuanBit > 0 )
504        {
505          // check quantization
506          for( Int idxVertex = 0 ; idxVertex < 4 ; idxVertex++ )
507          {
508            SYUVP sPred = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , idxVertex , pCurCuboid );
509            assert( ( ( rCuboid.P[idxVertex].Y - sPred.Y ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].Y - sPred.Y );
510            assert( ( ( rCuboid.P[idxVertex].U - sPred.U ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].U - sPred.U );
511            assert( ( ( rCuboid.P[idxVertex].V - sPred.V ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].V - sPred.V );
512          }
513        }
514      }
515    }
516  }
517
518  return( dErrorLuma + dErrorChroma );
519}
520
521Void TEnc3DAsymLUT::xxCollectData( TComPic * pCurPic , UInt refLayerIdc )
522{
523  Pel * pSrcY = m_pDsOrigPic->getAddr(COMPONENT_Y);
524  Pel * pSrcU = m_pDsOrigPic->getAddr(COMPONENT_Cb);
525  Pel * pSrcV = m_pDsOrigPic->getAddr(COMPONENT_Cr);
526  Int nStrideSrcY = m_pDsOrigPic->getStride(COMPONENT_Y);
527  Int nStrideSrcC = m_pDsOrigPic->getStride(COMPONENT_Cb);
528  TComPicYuv *pRecPic = pCurPic->getSlice(pCurPic->getCurrSliceIdx())->getBaseColPic(refLayerIdc)->getPicYuvRec();
529  Pel * pIRLY = pRecPic->getAddr(COMPONENT_Y);
530  Pel * pIRLU = pRecPic->getAddr(COMPONENT_Cb);
531  Pel * pIRLV = pRecPic->getAddr(COMPONENT_Cr);
532  Int nStrideILRY = pRecPic->getStride(COMPONENT_Y);
533  Int nStrideILRC = pRecPic->getStride(COMPONENT_Cb);
534#if R0179_ENC_OPT_3DLUT_SIZE
535  xReset3DArray( m_pColorInfo  , getMaxYSize() , getMaxCSize() , getMaxCSize() );
536  xReset3DArray( m_pColorInfoC , getMaxYSize() , getMaxCSize() , getMaxCSize() );
537#else
538  xReset3DArray( m_pColorInfo , xGetYSize() , xGetUSize() , xGetVSize() );
539  xReset3DArray( m_pColorInfoC , xGetYSize() , xGetUSize() , xGetVSize() );
540#endif
541
542  //alignment padding
543  pRecPic->setBorderExtension( false );
544  pRecPic->extendPicBorder();
545
546  TComSlice * pSlice = pCurPic->getSlice(pCurPic->getCurrSliceIdx());
547  UInt refLayerId = pSlice->getVPS()->getRefLayerId(pSlice->getLayerId(), refLayerIdc);
548  Window scalEL = pSlice->getPPS()->getScaledRefLayerWindowForLayer(refLayerId); 
549  TComPicYuv *pcRecPicBL = pSlice->getBaseColPic(refLayerIdc)->getPicYuvRec();
550  // borders of down-sampled picture
551  Int leftDS =  (scalEL.getWindowLeftOffset()*g_posScalingFactor[refLayerIdc][0]+(1<<15))>>16;
552  Int rightDS = pcRecPicBL->getWidth(COMPONENT_Y) - 1 + (((scalEL.getWindowRightOffset())*g_posScalingFactor[refLayerIdc][0]+(1<<15))>>16);
553  Int topDS = (((scalEL.getWindowTopOffset())*g_posScalingFactor[refLayerIdc][1]+(1<<15))>>16);
554  Int bottomDS = pcRecPicBL->getHeight(COMPONENT_Y) - 1 + (((scalEL.getWindowBottomOffset())*g_posScalingFactor[refLayerIdc][1]+(1<<15))>>16);
555  // overlapped region
556  Int left = max( 0 , leftDS );
557  Int right = min( pcRecPicBL->getWidth(COMPONENT_Y) - 1 , rightDS );
558  Int top = max( 0 , topDS );
559  Int bottom = min( pcRecPicBL->getHeight(COMPONENT_Y) - 1 , bottomDS );
560  // since we do data collection only for overlapped region, the border extension is good enough
561
562  m_dSumU = m_dSumV = 0;
563  m_nNChroma = 0;
564
565  for( Int i = top ; i <= bottom ; i++ )
566  {
567    Int iDS = i-topDS;
568    Int jDS = left-leftDS;
569    Int posSrcY = iDS * nStrideSrcY + jDS;
570    Int posIRLY = i * nStrideILRY + left;
571    Int posSrcUV = ( iDS >> 1 ) * nStrideSrcC + (jDS>>1);
572    Int posIRLUV = ( i >> 1 ) * nStrideILRC + (left>>1);
573    for( Int j = left ; j <= right ; j++ , posSrcY++ , posIRLY++ , posSrcUV += !( j & 0x01 ) , posIRLUV += !( j & 0x01 ) )
574    {
575      Int Y = pSrcY[posSrcY];
576      Int y = pIRLY[posIRLY];
577      Int U = pSrcU[posSrcUV];
578      Int u = pIRLU[posIRLUV];
579      Int V = pSrcV[posSrcUV];
580      Int v = pIRLV[posIRLUV];
581
582      // alignment
583      //filtering u, v for luma;
584      Int posIRLUVN =  posIRLUV + ((i&1)? nStrideILRC : -nStrideILRC);
585      if((j&1))
586      {
587        u = (pIRLU[posIRLUVN] + pIRLU[posIRLUVN+1] +(u + pIRLU[posIRLUV+1])*3 +4)>>3;
588        v = (pIRLV[posIRLUVN] + pIRLV[posIRLUVN+1] +(v + pIRLV[posIRLUV+1])*3 +4)>>3;
589      }
590      else
591      { 
592        u = (pIRLU[posIRLUVN] +u*3 +2)>>2;
593        v = (pIRLV[posIRLUVN] +v*3 +2)>>2;
594      }
595
596      m_dSumU += u;
597      m_dSumV += v;
598      m_nNChroma++;
599
600      SColorInfo sColorInfo;
601      SColorInfo & rCuboidColorInfo = m_pColorInfo[xGetYIdx(y)][xGetUIdx(u)][xGetVIdx(v)];
602
603      memset(&sColorInfo, 0, sizeof(SColorInfo));
604
605      sColorInfo.Ys = Y;
606      sColorInfo.ys = y;
607      sColorInfo.us = u;
608      sColorInfo.vs = v;
609      sColorInfo.Yy = Y * y;
610      sColorInfo.Yu = Y * u;
611      sColorInfo.Yv = Y * v;
612      sColorInfo.yy = y * y;
613      sColorInfo.yu = y * u;
614      sColorInfo.yv = y * v;
615      sColorInfo.uu = u * u;
616      sColorInfo.uv = u * v;
617      sColorInfo.vv = v * v;
618      sColorInfo.YY = Y * Y;
619      sColorInfo.= 1;
620
621      rCuboidColorInfo += sColorInfo;
622
623      if(!((i&1) || (j&1)))
624      {
625        // alignment
626        y =  (pIRLY[posIRLY] + pIRLY[posIRLY+nStrideILRY] + 1)>>1;
627
628        u = pIRLU[posIRLUV];
629        v = pIRLV[posIRLUV];
630
631        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[xGetYIdx(y)][xGetUIdx(u)][xGetVIdx(v)];
632
633        sColorInfo.Us = U;
634        sColorInfo.Vs = V;
635        sColorInfo.ys = y;
636        sColorInfo.us = u;
637        sColorInfo.vs = v;
638
639        sColorInfo.Uy = U * y;
640        sColorInfo.Uu = U * u;
641        sColorInfo.Uv = U * v;
642        sColorInfo.Vy = V * y;
643        sColorInfo.Vu = V * u;
644        sColorInfo.Vv = V * v;
645        sColorInfo.yy = y * y;
646        sColorInfo.yu = y * u;
647        sColorInfo.yv = y * v;
648        sColorInfo.uu = u * u;
649        sColorInfo.uv = u * v;
650        sColorInfo.vv = v * v;
651        sColorInfo.UU = U * U;
652        sColorInfo.VV = V * V;
653        sColorInfo.= 1;
654
655        rCuboidColorInfoC += sColorInfo;
656      }
657    }
658  }
659}
660
661Void TEnc3DAsymLUT::xxDerivePartNumLog2( TComSlice * pSlice , TEncCfg * pcCfg , Int & rOctantDepth , Int & rYPartNumLog2 , Bool bSignalPPS , Bool bElRapSliceTypeB )
662{
663  Int nPartNumLog2 = 4;
664  if( pSlice->getBaseColPic( pSlice->getInterLayerPredLayerIdc( 0 ) )->getSlice( 0 )->isIntra() )
665  {
666    nPartNumLog2 = xGetMaxPartNumLog2();
667  }
668
669  if( m_nAccuFrameBit && pSlice->getPPS()->getCGSFlag() ) 
670  {
671    Double dBitCost = 1.0 * m_nAccuFrameCGSBit / m_nAccuFrameBit;
672    nPartNumLog2 = m_nPrevFrameCGSPartNumLog2;
673
674    Double dBitCostT = 0.03;
675    if( dBitCost < dBitCostT / 6.0 )
676    {
677      nPartNumLog2++;
678    }
679    else if( dBitCost >= dBitCostT )
680    {
681      nPartNumLog2--;
682    }
683  }
684
685  nPartNumLog2 = Clip3( 0 , xGetMaxPartNumLog2()  , nPartNumLog2 );
686  xxMapPartNum2DepthYPart( nPartNumLog2 , rOctantDepth , rYPartNumLog2 );
687}
688
689Void TEnc3DAsymLUT::xxMapPartNum2DepthYPart( Int nPartNumLog2 , Int & rOctantDepth , Int & rYPartNumLog2 )
690{
691  for( Int y = getMaxYPartNumLog2() ; y >= 0 ; y-- )
692  {
693    for( Int depth = ( nPartNumLog2 - y ) >> 1 ; depth >= 0 ; depth-- )
694    {
695      if( y + 3 * depth == nPartNumLog2 )
696      {
697        rOctantDepth = depth;
698        rYPartNumLog2 = y;
699        return;
700      }
701    }
702  }
703  rOctantDepth = min( getMaxOctantDepth() , nPartNumLog2 / 3 );
704  rYPartNumLog2 = min( getMaxYPartNumLog2() , nPartNumLog2 - 3 * rOctantDepth );
705}
706
707Void TEnc3DAsymLUT::updatePicCGSBits( TComSlice * pcSlice , Int nPPSBit )
708{
709  for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
710  {
711    UInt refLayerIdc = pcSlice->getInterLayerPredLayerIdc(i);
712    m_nAccuFrameBit += pcSlice->getPic()->getFrameBit() + pcSlice->getBaseColPic(refLayerIdc)->getFrameBit();
713    m_dTotalFrameBit += pcSlice->getPic()->getFrameBit() + pcSlice->getBaseColPic(refLayerIdc)->getFrameBit();
714  }
715
716  m_nAccuFrameCGSBit += nPPSBit;
717  m_nTotalCGSBit += nPPSBit;
718  m_nPrevFrameCGSPartNumLog2 = getCurOctantDepth() * 3 + getCurYPartNumLog2();
719
720#if R0179_ENC_OPT_3DLUT_SIZE
721  Int nCurELFrameBit = pcSlice->getPic()->getFrameBit();
722  const Int nSliceType = pcSlice->getSliceType();
723  const Int nSliceTempLevel = pcSlice->getDepth();
724  m_nPrevELFrameBit[nSliceType][nSliceTempLevel] = m_nPrevELFrameBit[nSliceType][nSliceTempLevel] == 0 ? nCurELFrameBit:((m_nPrevELFrameBit[nSliceType][nSliceTempLevel]+nCurELFrameBit)>>1);
725#endif
726}
727
728#if R0179_ENC_OPT_3DLUT_SIZE
729
730Void TEnc3DAsymLUT::xxGetAllLutSizes(TComSlice *pSlice)
731{
732  Int iMaxYPartNumLog2, iMaxCPartNumLog2; 
733  Int iCurYPartNumLog2, iCurCPartNumLog2; 
734  Int iMaxAddYPartNumLog2; 
735  Int iNumELFrameBits = m_nPrevELFrameBit[pSlice->getSliceType()][pSlice->getDepth()];
736
737  xxMapPartNum2DepthYPart( xGetMaxPartNumLog2() , iMaxCPartNumLog2 , iMaxYPartNumLog2 );
738  iMaxAddYPartNumLog2 = iMaxYPartNumLog2; 
739  iMaxYPartNumLog2 += iMaxCPartNumLog2; 
740
741  //m_sLutSizes[0].iYPartNumLog2 = iMaxYPartNumLog2;
742  //m_sLutSizes[0].iCPartNumLog2 = iMaxCPartNumLog2;
743  m_nTotalLutSizes = 0; 
744
745
746  for(iCurYPartNumLog2 = iMaxYPartNumLog2; iCurYPartNumLog2 >= 0; iCurYPartNumLog2--) 
747  {
748    for(iCurCPartNumLog2 = iMaxCPartNumLog2; iCurCPartNumLog2 >= 0; iCurCPartNumLog2--) 
749    {
750       // try more sizes
751      if(iCurCPartNumLog2 <= iCurYPartNumLog2  && 
752         (m_nNumLUTBits[iCurYPartNumLog2][iCurCPartNumLog2] < (iNumELFrameBits>>1)) && 
753         m_nTotalLutSizes < MAX_NUM_LUT_SIZES)
754      {
755        m_sLutSizes[m_nTotalLutSizes].iYPartNumLog2 = iCurYPartNumLog2; 
756        m_sLutSizes[m_nTotalLutSizes].iCPartNumLog2 = iCurCPartNumLog2; 
757        m_nTotalLutSizes ++; 
758      }
759    }
760  }
761
762}
763
764Void TEnc3DAsymLUT::xxCopyColorInfo( SColorInfo *** dst, SColorInfo *** src ,  SColorInfo *** dstC, SColorInfo *** srcC )
765{
766  Int yIdx, uIdx, vIdx; 
767
768  // copy from pColorInfo to pMaxColorInfo
769  for(yIdx = 0; yIdx < xGetYSize(); yIdx++)
770  {
771    for(uIdx = 0; uIdx < xGetUSize(); uIdx++)
772    {
773      for(vIdx = 0; vIdx < xGetVSize(); vIdx++)
774      {
775        dst [yIdx][uIdx][vIdx] = src [yIdx][uIdx][vIdx];
776        dstC[yIdx][uIdx][vIdx] = srcC[yIdx][uIdx][vIdx];
777      }
778    }
779  }
780}
781
782Void TEnc3DAsymLUT::xxAddColorInfo( Int yIdx, Int uIdx, Int vIdx, Int iYDiffLog2, Int iCDiffLog2 )
783{
784  SColorInfo & rCuboidColorInfo  = m_pColorInfo [yIdx][uIdx][vIdx];
785  SColorInfo & rCuboidColorInfoC = m_pColorInfoC[yIdx][uIdx][vIdx];
786 
787  for( Int i = 0; i < (1<<iYDiffLog2); i++)
788  {
789    for (Int j = 0; j < (1<<iCDiffLog2); j++)
790    {
791      for(Int k = 0; k < (1<<iCDiffLog2); k++)
792      {
793        rCuboidColorInfo  += m_pMaxColorInfo [(yIdx<<iYDiffLog2)+i][(uIdx<<iCDiffLog2)+j][(vIdx<<iCDiffLog2)+k];
794        rCuboidColorInfoC += m_pMaxColorInfoC[(yIdx<<iYDiffLog2)+i][(uIdx<<iCDiffLog2)+j][(vIdx<<iCDiffLog2)+k];
795      }
796    }
797  }
798}
799
800Void TEnc3DAsymLUT::xxConsolidateData( SLUTSize *pCurLUTSize, SLUTSize *pMaxLUTSize )
801{
802  Int yIdx, uIdx, vIdx; 
803  Int iYDiffLog2, iCDiffLog2;
804  Int nYSize = 1<< pMaxLUTSize->iYPartNumLog2;
805  Int nCSize = 1<< pMaxLUTSize->iCPartNumLog2;
806
807  iYDiffLog2 = pMaxLUTSize->iYPartNumLog2-pCurLUTSize->iYPartNumLog2;
808  iCDiffLog2 = pMaxLUTSize->iCPartNumLog2-pCurLUTSize->iCPartNumLog2;
809
810  //assert(pMaxLUTSize->iCPartNumLog2 >= pCurLUTSize->iCPartNumLog2 && pMaxLUTSize->iYPartNumLog2 >= pCurLUTSize->iYPartNumLog2);
811  if (iYDiffLog2 == 0 && iCDiffLog2 == 0) // shouldn't have to do anything
812  {
813    xxCopyColorInfo(m_pColorInfo, m_pMaxColorInfo, m_pColorInfoC, m_pMaxColorInfoC);
814    return; 
815  }
816
817  xReset3DArray( m_pColorInfo  ,  1<<pMaxLUTSize->iYPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2 );
818  xReset3DArray( m_pColorInfoC ,  1<<pMaxLUTSize->iYPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2 );
819
820  for(yIdx = 0; yIdx < nYSize; yIdx++)
821  {
822    for(uIdx = 0; uIdx < nCSize; uIdx++)
823    {
824      for(vIdx = 0; vIdx < nCSize; vIdx++)
825      {
826        const SColorInfo & rCuboidSrc   = m_pMaxColorInfo [yIdx][uIdx][vIdx];
827        const SColorInfo & rCuboidSrcC  = m_pMaxColorInfoC[yIdx][uIdx][vIdx];
828       
829        Int yIdx2, uIdx2, vIdx2; 
830        yIdx2 = yIdx>>iYDiffLog2; 
831        uIdx2 = uIdx>>iCDiffLog2;
832        vIdx2 = vIdx>>iCDiffLog2; 
833
834        m_pColorInfo [yIdx2][uIdx2][vIdx2] += rCuboidSrc;
835        m_pColorInfoC[yIdx2][uIdx2][vIdx2] += rCuboidSrcC;
836      }
837    }
838  }
839}
840
841Void TEnc3DAsymLUT::update3DAsymLUTParam( TEnc3DAsymLUT * pSrc )
842{
843  assert( pSrc->getMaxOctantDepth() == getMaxOctantDepth() && pSrc->getMaxYPartNumLog2() == getMaxYPartNumLog2() );
844  xUpdatePartitioning( pSrc->getCurOctantDepth(), pSrc->getCurYPartNumLog2(), pSrc->getAdaptChromaThresholdU(), pSrc->getAdaptChromaThresholdV() );
845  setResQuantBit( pSrc->getResQuantBit() );
846}
847#endif
848#endif
Note: See TracBrowser for help on using the repository browser.