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

Last change on this file since 1465 was 1440, checked in by seregin, 9 years ago

remove virtual for create functions in *3DAsymLUT classes, signature is anyway different

File size: 34.9 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-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 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          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 ,
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 += 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 ,
226            rCuboid.P[0].U , rCuboid.P[1].U , rCuboid.P[2].U , rCuboid.P[3].U );
227          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 ,
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  xMapPartNum2DepthYPart( nMaxPartNumLog2 , nCurOctantDepth , nCurYPartNumLog2 ); 
256  xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV ); 
257  xCollectData( pCurPic , refLayerIdc );
258  xCopyColorInfo(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  xGetAllLutSizes(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    xConsolidateData( &m_sLutSizes[i], &sMaxLutSize );
294 
295    dCurError = xDeriveVertexes(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      xCollectData( pCurPic , refLayerIdc );
332
333      dCurError = xDeriveVertexes( 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  {
359    xConsolidateData( &m_sLutSizes[iBestLUTSizeIdx], &sMaxLutSize );
360  }
361
362  //    xCollectData( pCurPic , refLayerIdc );
363  for( Int nResQuanBit = 1 ; nResQuanBit < 4 ; nResQuanBit++ )
364  {
365    dCurError = xDeriveVertexes( nResQuanBit , m_pEncCuboid );
366
367    setResQuantBit( nResQuanBit );
368    xSaveCuboids( m_pEncCuboid ); 
369    m_pEncCavlc->xCode3DAsymLUT( this ); 
370    iNumBitsCurSize = m_pEncCavlc->getNumberOfWrittenBits();
371    dCurCost = dCurError/dDistFactor + dFrameLambda*(Double)(iNumBitsCurSize-iNumBitsCurSizeSave);   
372
373    iNumBitsCurSizeSave = iNumBitsCurSize;
374    if(dCurCost < dMinCost)
375    {
376      nBestResQuanBit = nResQuanBit;
377      SCuboid *** tmp = m_pBestEncCuboid;
378      m_pBestEncCuboid = m_pEncCuboid;
379      m_pEncCuboid = tmp;
380      dMinCost = dCurCost; 
381      dMinError = dCurError;
382    }
383    else
384    {
385      break;
386    }
387  }
388   
389  setResQuantBit( nBestResQuanBit );
390  xSaveCuboids( m_pBestEncCuboid );
391
392  // update LUT size stats
393  for(Int iLutSizeY = 0; iLutSizeY < MAX_Y_SIZE; iLutSizeY++)
394  {
395    for(Int iLutSizeC = 0; iLutSizeC < MAX_C_SIZE; iLutSizeC++) 
396    {
397      if(nTmpLutBits[iLutSizeY][iLutSizeC] != 0) 
398        m_nNumLUTBits[iLutSizeY][iLutSizeC] =  (m_nNumLUTBits[iLutSizeY][iLutSizeC] + nTmpLutBits[iLutSizeY][iLutSizeC]*3+2)>>2; // update with new stats
399    }
400  }
401
402  // return cost rather than error
403  return( dMinCost );
404}
405#endif
406
407Double TEnc3DAsymLUT::derive3DAsymLUT( TComSlice * pSlice, TComPic * pCurPic, UInt refLayerIdc, TEncCfg * pCfg, Bool bSignalPPS, Bool bElRapSliceTypeB )
408{
409  m_nLUTBitDepth = pCfg->getCGSLUTBit();
410  Int nCurYPartNumLog2 = 0 , nCurOctantDepth = 0; 
411  xDerivePartNumLog2( pSlice , pCfg , nCurOctantDepth , nCurYPartNumLog2 , bSignalPPS , bElRapSliceTypeB );
412
413  Int nBestResQuanBit = 0;
414  Int nBestAdaptCThresholdU = 1 << ( getInputBitDepthC() - 1 );
415  Int nBestAdaptCThresholdV = 1 << ( getInputBitDepthC() - 1 );
416  Int nBestOctantDepth = nCurOctantDepth;
417  Int nBestYPartNumLog2 = nCurYPartNumLog2;
418  Int nTargetLoop = 1 + ( pCfg->getCGSAdaptChroma() && ( nCurOctantDepth == 1 || ( nCurOctantDepth * 3 + nCurYPartNumLog2 ) >= 5 ) );
419  Double dMinError = MAX_DOUBLE;
420  for( Int nLoop = 0 ; nLoop < nTargetLoop ; nLoop++ )
421  {
422    Int nAdaptCThresholdU = 1 << ( getInputBitDepthC() - 1 );
423    Int nAdaptCThresholdV = 1 << ( getInputBitDepthC() - 1 );
424    if( nLoop > 0 )
425    {
426      nAdaptCThresholdU = ( Int )( m_dSumU / m_nNChroma + 0.5 );
427      nAdaptCThresholdV = ( Int )( m_dSumV / m_nNChroma + 0.5 );
428      if( nCurOctantDepth > 1 )
429      {
430        nCurOctantDepth = 1;
431        nCurYPartNumLog2 = 2;
432      }
433      if( nAdaptCThresholdU == nBestAdaptCThresholdU && nAdaptCThresholdV == nBestAdaptCThresholdV
434        && nCurOctantDepth == nBestOctantDepth && nCurYPartNumLog2 == nBestYPartNumLog2 )
435        break;
436    }
437
438    xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2 , nAdaptCThresholdU , nAdaptCThresholdV );
439    xCollectData( pCurPic , refLayerIdc );
440    for( Int nResQuanBit = 0 ; nResQuanBit < 4 ; nResQuanBit++ )
441    {
442      Double dError = xDeriveVertexes( nResQuanBit , m_pEncCuboid ) / ( 1 + ( nResQuanBit > 0 ) * 0.001 * ( pSlice->getDepth() + 1 ) );
443      if( dError <= dMinError )
444      {
445        nBestResQuanBit = nResQuanBit;
446        nBestAdaptCThresholdU = nAdaptCThresholdU;
447        nBestAdaptCThresholdV = nAdaptCThresholdV;
448        nBestOctantDepth = nCurOctantDepth;
449        nBestYPartNumLog2 = nCurYPartNumLog2;
450        SCuboid *** tmp = m_pBestEncCuboid;
451        m_pBestEncCuboid = m_pEncCuboid;
452        m_pEncCuboid = tmp;
453        dMinError = dError;
454      }
455      else
456      {
457        break;
458      }
459    }
460  }
461
462  setResQuantBit( nBestResQuanBit );
463  xUpdatePartitioning( nBestOctantDepth, nBestYPartNumLog2, nBestAdaptCThresholdU, nBestAdaptCThresholdV );
464
465  xSaveCuboids( m_pBestEncCuboid );
466  return( dMinError );
467}
468
469Double TEnc3DAsymLUT::xDeriveVertexes( Int nResQuanBit, SCuboid *** pCurCuboid )
470{
471  Double dErrorLuma = 0 , dErrorChroma = 0;
472  Int nYSize = 1 << ( getCurOctantDepth() + getCurYPartNumLog2() );
473  Int nUVSize = 1 << getCurOctantDepth();
474
475  for( Int yIdx = 0 ; yIdx < nYSize ; yIdx++ )
476  {
477    for( Int uIdx = 0 ; uIdx < nUVSize ; uIdx++ )
478    {
479      for( Int vIdx = 0 ; vIdx < nUVSize ; vIdx++ )
480      {
481        SColorInfo & rCuboidColorInfo = m_pColorInfo[yIdx][uIdx][vIdx];
482        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[yIdx][uIdx][vIdx];
483        SCuboid & rCuboid = pCurCuboid[yIdx][uIdx][vIdx];
484
485        for( Int idxVertex = 0 ; idxVertex < 4 ; idxVertex++ )
486        {
487          rCuboid.P[idxVertex] = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , idxVertex , pCurCuboid );
488        }
489
490        if( rCuboidColorInfo.N > 0 )
491        {
492          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 ,
493            rCuboid.P[0].Y , rCuboid.P[1].Y , rCuboid.P[2].Y , rCuboid.P[3].Y , nResQuanBit );
494        }
495
496        if( rCuboidColorInfoC.N > 0 )
497        {
498          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 ,
499            rCuboid.P[0].U , rCuboid.P[1].U , rCuboid.P[2].U , rCuboid.P[3].U , nResQuanBit );
500
501          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 ,
502            rCuboid.P[0].V , rCuboid.P[1].V , rCuboid.P[2].V , rCuboid.P[3].V , nResQuanBit );
503        }
504
505        if( nResQuanBit > 0 )
506        {
507          // check quantization
508          for( Int idxVertex = 0 ; idxVertex < 4 ; idxVertex++ )
509          {
510            SYUVP sPred = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , idxVertex , pCurCuboid );
511            assert( ( ( rCuboid.P[idxVertex].Y - sPred.Y ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].Y - sPred.Y );
512            assert( ( ( rCuboid.P[idxVertex].U - sPred.U ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].U - sPred.U );
513            assert( ( ( rCuboid.P[idxVertex].V - sPred.V ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].V - sPred.V );
514          }
515        }
516      }
517    }
518  }
519
520  return( dErrorLuma + dErrorChroma );
521}
522
523Void TEnc3DAsymLUT::xCollectData( TComPic * pCurPic, UInt refLayerIdc )
524{
525  Pel * pSrcY = m_pDsOrigPic->getAddr(COMPONENT_Y);
526  Pel * pSrcU = m_pDsOrigPic->getAddr(COMPONENT_Cb);
527  Pel * pSrcV = m_pDsOrigPic->getAddr(COMPONENT_Cr);
528  Int nStrideSrcY = m_pDsOrigPic->getStride(COMPONENT_Y);
529  Int nStrideSrcC = m_pDsOrigPic->getStride(COMPONENT_Cb);
530  TComPicYuv *pRecPic = pCurPic->getSlice(pCurPic->getCurrSliceIdx())->getBaseColPic(refLayerIdc)->getPicYuvRec();
531  Pel * pIRLY = pRecPic->getAddr(COMPONENT_Y);
532  Pel * pIRLU = pRecPic->getAddr(COMPONENT_Cb);
533  Pel * pIRLV = pRecPic->getAddr(COMPONENT_Cr);
534  Int nStrideILRY = pRecPic->getStride(COMPONENT_Y);
535  Int nStrideILRC = pRecPic->getStride(COMPONENT_Cb);
536#if R0179_ENC_OPT_3DLUT_SIZE
537  xReset3DArray( m_pColorInfo  , getMaxYSize() , getMaxCSize() , getMaxCSize() );
538  xReset3DArray( m_pColorInfoC , getMaxYSize() , getMaxCSize() , getMaxCSize() );
539#else
540  xReset3DArray( m_pColorInfo , xGetYSize() , xGetUSize() , xGetVSize() );
541  xReset3DArray( m_pColorInfoC , xGetYSize() , xGetUSize() , xGetVSize() );
542#endif
543
544  //alignment padding
545  pRecPic->setBorderExtension( false );
546  pRecPic->extendPicBorder();
547
548  TComSlice * pSlice = pCurPic->getSlice(pCurPic->getCurrSliceIdx());
549  UInt refLayerId = pSlice->getVPS()->getRefLayerId(pSlice->getLayerId(), refLayerIdc);
550  Window scalEL = pSlice->getPPS()->getScaledRefLayerWindowForLayer(refLayerId); 
551  TComPicYuv *pcRecPicBL = pSlice->getBaseColPic(refLayerIdc)->getPicYuvRec();
552  // borders of down-sampled picture
553  Int leftDS =  (scalEL.getWindowLeftOffset() * pSlice->getPic()->getPosScalingFactor(refLayerIdc, 0)+(1<<15))>>16;
554  Int rightDS = pcRecPicBL->getWidth(COMPONENT_Y) - 1 + (((scalEL.getWindowRightOffset()) * pSlice->getPic()->getPosScalingFactor(refLayerIdc, 0)+(1<<15))>>16);
555  Int topDS = (((scalEL.getWindowTopOffset()) * pSlice->getPic()->getPosScalingFactor(refLayerIdc, 1)+(1<<15))>>16);
556  Int bottomDS = pcRecPicBL->getHeight(COMPONENT_Y) - 1 + (((scalEL.getWindowBottomOffset()) * pSlice->getPic()->getPosScalingFactor(refLayerIdc, 1)+(1<<15))>>16);
557  // overlapped region
558  Int left = max( 0 , leftDS );
559  Int right = min( pcRecPicBL->getWidth(COMPONENT_Y) - 1 , rightDS );
560  Int top = max( 0 , topDS );
561  Int bottom = min( pcRecPicBL->getHeight(COMPONENT_Y) - 1 , bottomDS );
562  // since we do data collection only for overlapped region, the border extension is good enough
563
564  m_dSumU = m_dSumV = 0;
565  m_nNChroma = 0;
566
567  for( Int i = top ; i <= bottom ; i++ )
568  {
569    Int iDS = i-topDS;
570    Int jDS = left-leftDS;
571    Int posSrcY = iDS * nStrideSrcY + jDS;
572    Int posIRLY = i * nStrideILRY + left;
573    Int posSrcUV = ( iDS >> 1 ) * nStrideSrcC + (jDS>>1);
574    Int posIRLUV = ( i >> 1 ) * nStrideILRC + (left>>1);
575    for( Int j = left ; j <= right ; j++ , posSrcY++ , posIRLY++ , posSrcUV += !( j & 0x01 ) , posIRLUV += !( j & 0x01 ) )
576    {
577      Int Y = pSrcY[posSrcY];
578      Int y = pIRLY[posIRLY];
579      Int U = pSrcU[posSrcUV];
580      Int u = pIRLU[posIRLUV];
581      Int V = pSrcV[posSrcUV];
582      Int v = pIRLV[posIRLUV];
583
584      // alignment
585      //filtering u, v for luma;
586      Int posIRLUVN =  posIRLUV + ((i&1)? nStrideILRC : -nStrideILRC);
587      if((j&1))
588      {
589        u = (pIRLU[posIRLUVN] + pIRLU[posIRLUVN+1] +(u + pIRLU[posIRLUV+1])*3 +4)>>3;
590        v = (pIRLV[posIRLUVN] + pIRLV[posIRLUVN+1] +(v + pIRLV[posIRLUV+1])*3 +4)>>3;
591      }
592      else
593      { 
594        u = (pIRLU[posIRLUVN] +u*3 +2)>>2;
595        v = (pIRLV[posIRLUVN] +v*3 +2)>>2;
596      }
597
598      m_dSumU += u;
599      m_dSumV += v;
600      m_nNChroma++;
601
602      SColorInfo sColorInfo;
603      SColorInfo & rCuboidColorInfo = m_pColorInfo[xGetYIdx(y)][xGetUIdx(u)][xGetVIdx(v)];
604
605      memset(&sColorInfo, 0, sizeof(SColorInfo));
606
607      sColorInfo.Ys = Y;
608      sColorInfo.ys = y;
609      sColorInfo.us = u;
610      sColorInfo.vs = v;
611      sColorInfo.Yy = Y * y;
612      sColorInfo.Yu = Y * u;
613      sColorInfo.Yv = Y * v;
614      sColorInfo.yy = y * y;
615      sColorInfo.yu = y * u;
616      sColorInfo.yv = y * v;
617      sColorInfo.uu = u * u;
618      sColorInfo.uv = u * v;
619      sColorInfo.vv = v * v;
620      sColorInfo.YY = Y * Y;
621      sColorInfo.= 1;
622
623      rCuboidColorInfo += sColorInfo;
624
625      if(!((i&1) || (j&1)))
626      {
627        // alignment
628        y =  (pIRLY[posIRLY] + pIRLY[posIRLY+nStrideILRY] + 1)>>1;
629
630        u = pIRLU[posIRLUV];
631        v = pIRLV[posIRLUV];
632
633        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[xGetYIdx(y)][xGetUIdx(u)][xGetVIdx(v)];
634
635        sColorInfo.Us = U;
636        sColorInfo.Vs = V;
637        sColorInfo.ys = y;
638        sColorInfo.us = u;
639        sColorInfo.vs = v;
640
641        sColorInfo.Uy = U * y;
642        sColorInfo.Uu = U * u;
643        sColorInfo.Uv = U * v;
644        sColorInfo.Vy = V * y;
645        sColorInfo.Vu = V * u;
646        sColorInfo.Vv = V * v;
647        sColorInfo.yy = y * y;
648        sColorInfo.yu = y * u;
649        sColorInfo.yv = y * v;
650        sColorInfo.uu = u * u;
651        sColorInfo.uv = u * v;
652        sColorInfo.vv = v * v;
653        sColorInfo.UU = U * U;
654        sColorInfo.VV = V * V;
655        sColorInfo.= 1;
656
657        rCuboidColorInfoC += sColorInfo;
658      }
659    }
660  }
661}
662
663Void TEnc3DAsymLUT::xDerivePartNumLog2( TComSlice * pSlice, TEncCfg * pcCfg, Int & rOctantDepth, Int & rYPartNumLog2, Bool bSignalPPS, Bool bElRapSliceTypeB )
664{
665  Int nPartNumLog2 = 4;
666  if( pSlice->getBaseColPic( pSlice->getInterLayerPredLayerIdc( 0 ) )->getSlice( 0 )->isIntra() )
667  {
668    nPartNumLog2 = xGetMaxPartNumLog2();
669  }
670
671  if( m_nAccuFrameBit && pSlice->getPPS()->getCGSFlag() ) 
672  {
673    Double dBitCost = 1.0 * m_nAccuFrameCGSBit / m_nAccuFrameBit;
674    nPartNumLog2 = m_nPrevFrameCGSPartNumLog2;
675
676    Double dBitCostT = 0.03;
677    if( dBitCost < dBitCostT / 6.0 )
678    {
679      nPartNumLog2++;
680    }
681    else if( dBitCost >= dBitCostT )
682    {
683      nPartNumLog2--;
684    }
685  }
686
687  nPartNumLog2 = Clip3( 0 , xGetMaxPartNumLog2()  , nPartNumLog2 );
688  xMapPartNum2DepthYPart( nPartNumLog2 , rOctantDepth , rYPartNumLog2 );
689}
690
691Void TEnc3DAsymLUT::xMapPartNum2DepthYPart( Int nPartNumLog2, Int & rOctantDepth, Int & rYPartNumLog2 )
692{
693  for( Int y = getMaxYPartNumLog2() ; y >= 0 ; y-- )
694  {
695    for( Int depth = ( nPartNumLog2 - y ) >> 1 ; depth >= 0 ; depth-- )
696    {
697      if( y + 3 * depth == nPartNumLog2 )
698      {
699        rOctantDepth = depth;
700        rYPartNumLog2 = y;
701        return;
702      }
703    }
704  }
705  rOctantDepth = min( getMaxOctantDepth() , nPartNumLog2 / 3 );
706  rYPartNumLog2 = min( getMaxYPartNumLog2() , nPartNumLog2 - 3 * rOctantDepth );
707}
708
709Void TEnc3DAsymLUT::updatePicCGSBits( TComSlice * pcSlice, Int nPPSBit )
710{
711  for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
712  {
713    UInt refLayerIdc = pcSlice->getInterLayerPredLayerIdc(i);
714    m_nAccuFrameBit += pcSlice->getPic()->getFrameBit() + pcSlice->getBaseColPic(refLayerIdc)->getFrameBit();
715    m_dTotalFrameBit += pcSlice->getPic()->getFrameBit() + pcSlice->getBaseColPic(refLayerIdc)->getFrameBit();
716  }
717
718  m_nAccuFrameCGSBit += nPPSBit;
719  m_nTotalCGSBit += nPPSBit;
720  m_nPrevFrameCGSPartNumLog2 = getCurOctantDepth() * 3 + getCurYPartNumLog2();
721
722#if R0179_ENC_OPT_3DLUT_SIZE
723  Int nCurELFrameBit = pcSlice->getPic()->getFrameBit();
724  const Int nSliceType = pcSlice->getSliceType();
725  const Int nSliceTempLevel = pcSlice->getDepth();
726  m_nPrevELFrameBit[nSliceType][nSliceTempLevel] = m_nPrevELFrameBit[nSliceType][nSliceTempLevel] == 0 ? nCurELFrameBit:((m_nPrevELFrameBit[nSliceType][nSliceTempLevel]+nCurELFrameBit)>>1);
727#endif
728}
729
730#if R0179_ENC_OPT_3DLUT_SIZE
731
732Void TEnc3DAsymLUT::xGetAllLutSizes(TComSlice *pSlice)
733{
734  Int iMaxYPartNumLog2, iMaxCPartNumLog2; 
735  Int iCurYPartNumLog2, iCurCPartNumLog2; 
736  Int iMaxAddYPartNumLog2; 
737  Int iNumELFrameBits = m_nPrevELFrameBit[pSlice->getSliceType()][pSlice->getDepth()];
738
739  xMapPartNum2DepthYPart( xGetMaxPartNumLog2(), iMaxCPartNumLog2, iMaxYPartNumLog2 );
740  iMaxAddYPartNumLog2 = iMaxYPartNumLog2; 
741  iMaxYPartNumLog2 += iMaxCPartNumLog2; 
742
743  //m_sLutSizes[0].iYPartNumLog2 = iMaxYPartNumLog2;
744  //m_sLutSizes[0].iCPartNumLog2 = iMaxCPartNumLog2;
745  m_nTotalLutSizes = 0; 
746
747
748  for(iCurYPartNumLog2 = iMaxYPartNumLog2; iCurYPartNumLog2 >= 0; iCurYPartNumLog2--) 
749  {
750    for(iCurCPartNumLog2 = iMaxCPartNumLog2; iCurCPartNumLog2 >= 0; iCurCPartNumLog2--) 
751    {
752       // try more sizes
753      if(iCurCPartNumLog2 <= iCurYPartNumLog2  && 
754         (m_nNumLUTBits[iCurYPartNumLog2][iCurCPartNumLog2] < (iNumELFrameBits>>1)) && 
755         m_nTotalLutSizes < MAX_NUM_LUT_SIZES)
756      {
757        m_sLutSizes[m_nTotalLutSizes].iYPartNumLog2 = iCurYPartNumLog2; 
758        m_sLutSizes[m_nTotalLutSizes].iCPartNumLog2 = iCurCPartNumLog2; 
759        m_nTotalLutSizes ++; 
760      }
761    }
762  }
763
764}
765
766Void TEnc3DAsymLUT::xCopyColorInfo( SColorInfo *** dst, SColorInfo *** src,  SColorInfo *** dstC, SColorInfo *** srcC )
767{
768  Int yIdx, uIdx, vIdx; 
769
770  // copy from pColorInfo to pMaxColorInfo
771  for(yIdx = 0; yIdx < xGetYSize(); yIdx++)
772  {
773    for(uIdx = 0; uIdx < xGetUSize(); uIdx++)
774    {
775      for(vIdx = 0; vIdx < xGetVSize(); vIdx++)
776      {
777        dst [yIdx][uIdx][vIdx] = src [yIdx][uIdx][vIdx];
778        dstC[yIdx][uIdx][vIdx] = srcC[yIdx][uIdx][vIdx];
779      }
780    }
781  }
782}
783
784Void TEnc3DAsymLUT::xAddColorInfo( Int yIdx, Int uIdx, Int vIdx, Int iYDiffLog2, Int iCDiffLog2 )
785{
786  SColorInfo & rCuboidColorInfo  = m_pColorInfo [yIdx][uIdx][vIdx];
787  SColorInfo & rCuboidColorInfoC = m_pColorInfoC[yIdx][uIdx][vIdx];
788 
789  for( Int i = 0; i < (1<<iYDiffLog2); i++)
790  {
791    for (Int j = 0; j < (1<<iCDiffLog2); j++)
792    {
793      for(Int k = 0; k < (1<<iCDiffLog2); k++)
794      {
795        rCuboidColorInfo  += m_pMaxColorInfo [(yIdx<<iYDiffLog2)+i][(uIdx<<iCDiffLog2)+j][(vIdx<<iCDiffLog2)+k];
796        rCuboidColorInfoC += m_pMaxColorInfoC[(yIdx<<iYDiffLog2)+i][(uIdx<<iCDiffLog2)+j][(vIdx<<iCDiffLog2)+k];
797      }
798    }
799  }
800}
801
802Void TEnc3DAsymLUT::xConsolidateData( SLUTSize *pCurLUTSize, SLUTSize *pMaxLUTSize )
803{
804  Int yIdx, uIdx, vIdx; 
805  Int iYDiffLog2, iCDiffLog2;
806  Int nYSize = 1<< pMaxLUTSize->iYPartNumLog2;
807  Int nCSize = 1<< pMaxLUTSize->iCPartNumLog2;
808
809  iYDiffLog2 = pMaxLUTSize->iYPartNumLog2-pCurLUTSize->iYPartNumLog2;
810  iCDiffLog2 = pMaxLUTSize->iCPartNumLog2-pCurLUTSize->iCPartNumLog2;
811
812  //assert(pMaxLUTSize->iCPartNumLog2 >= pCurLUTSize->iCPartNumLog2 && pMaxLUTSize->iYPartNumLog2 >= pCurLUTSize->iYPartNumLog2);
813  if (iYDiffLog2 == 0 && iCDiffLog2 == 0) // shouldn't have to do anything
814  {
815    xCopyColorInfo(m_pColorInfo, m_pMaxColorInfo, m_pColorInfoC, m_pMaxColorInfoC);
816    return; 
817  }
818
819  xReset3DArray( m_pColorInfo,   1<<pMaxLUTSize->iYPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2 );
820  xReset3DArray( m_pColorInfoC,  1<<pMaxLUTSize->iYPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2, 1<<pMaxLUTSize->iCPartNumLog2 );
821
822  for(yIdx = 0; yIdx < nYSize; yIdx++)
823  {
824    for(uIdx = 0; uIdx < nCSize; uIdx++)
825    {
826      for(vIdx = 0; vIdx < nCSize; vIdx++)
827      {
828        const SColorInfo & rCuboidSrc   = m_pMaxColorInfo [yIdx][uIdx][vIdx];
829        const SColorInfo & rCuboidSrcC  = m_pMaxColorInfoC[yIdx][uIdx][vIdx];
830       
831        Int yIdx2, uIdx2, vIdx2; 
832        yIdx2 = yIdx>>iYDiffLog2; 
833        uIdx2 = uIdx>>iCDiffLog2;
834        vIdx2 = vIdx>>iCDiffLog2; 
835
836        m_pColorInfo [yIdx2][uIdx2][vIdx2] += rCuboidSrc;
837        m_pColorInfoC[yIdx2][uIdx2][vIdx2] += rCuboidSrcC;
838      }
839    }
840  }
841}
842
843Void TEnc3DAsymLUT::update3DAsymLUTParam( TEnc3DAsymLUT * pSrc )
844{
845  assert( pSrc->getMaxOctantDepth() == getMaxOctantDepth() && pSrc->getMaxYPartNumLog2() == getMaxYPartNumLog2() );
846  xUpdatePartitioning( pSrc->getCurOctantDepth(), pSrc->getCurYPartNumLog2(), pSrc->getAdaptChromaThresholdU(), pSrc->getAdaptChromaThresholdV() );
847  setResQuantBit( pSrc->getResQuantBit() );
848}
849#endif
850#endif
Note: See TracBrowser for help on using the repository browser.