source: SHVCSoftware/branches/SHM-upgrade/source/Lib/TLibEncoder/TEnc3DAsymLUT.cpp @ 996

Last change on this file since 996 was 916, checked in by seregin, 10 years ago

initial porting

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