source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibCommon/TComUpsampleFilter.cpp @ 1500

Last change on this file since 1500 was 1500, checked in by seregin, 8 years ago

replace 3 with CHROMA_444

  • Property svn:eol-style set to native
File size: 14.0 KB
Line 
1#include "CommonDef.h"
2#if SVC_EXTENSION
3#include "TComUpsampleFilter.h"
4
5const Int TComUpsampleFilter::m_lumaFixedFilter[16][NTAPS_US_LUMA] =
6{
7  {  0, 0,   0, 64,  0,   0,  0,  0 },
8  {  0, 1,  -3, 63,  4,  -2,  1,  0 },
9  { -1, 2,  -5, 62,  8,  -3,  1,  0 },
10  { -1, 3,  -8, 60, 13,  -4,  1,  0 },
11  { -1, 4, -10, 58, 17,  -5,  1,  0 },
12  { -1, 4, -11, 52, 26,  -8,  3, -1 }, // <-> actual phase shift 1/3, used for spatial scalability x1.5
13  { -1, 3,  -9, 47, 31, -10,  4, -1 },
14  { -1, 4, -11, 45, 34, -10,  4, -1 },
15  { -1, 4, -11, 40, 40, -11,  4, -1 }, // <-> actual phase shift 1/2, equal to HEVC MC, used for spatial scalability x2
16  { -1, 4, -10, 34, 45, -11,  4, -1 },
17  { -1, 4, -10, 31, 47,  -9,  3, -1 },
18  { -1, 3,  -8, 26, 52, -11,  4, -1 }, // <-> actual phase shift 2/3, used for spatial scalability x1.5
19  {  0, 1,  -5, 17, 58, -10,  4, -1 },
20  {  0, 1,  -4, 13, 60,  -8,  3, -1 },
21  {  0, 1,  -3,  8, 62,  -5,  2, -1 },
22  {  0, 1,  -2,  4, 63,  -3,  1,  0 }
23};
24
25const Int TComUpsampleFilter::m_chromaFixedFilter[16][NTAPS_US_CHROMA] =
26{
27  {  0, 64,  0,  0 },
28  { -2, 62,  4,  0 },
29  { -2, 58, 10, -2 },
30  { -4, 56, 14, -2 },
31  { -4, 54, 16, -2 }, // <-> actual phase shift 1/4,equal to HEVC MC, used for spatial scalability x1.5 (only for accurate Chroma alignement)
32  { -6, 52, 20, -2 }, // <-> actual phase shift 1/3, used for spatial scalability x1.5
33  { -6, 46, 28, -4 }, // <-> actual phase shift 3/8,equal to HEVC MC, used for spatial scalability x2 (only for accurate Chroma alignement)
34  { -4, 42, 30, -4 },
35  { -4, 36, 36, -4 }, // <-> actual phase shift 1/2,equal to HEVC MC, used for spatial scalability x2
36  { -4, 30, 42, -4 }, // <-> actual phase shift 7/12, used for spatial scalability x1.5 (only for accurate Chroma alignement)
37  { -4, 28, 46, -6 },
38  { -2, 20, 52, -6 }, // <-> actual phase shift 2/3, used for spatial scalability x1.5
39  { -2, 16, 54, -4 },
40  { -2, 14, 56, -4 },
41  { -2, 10, 58, -2 }, // <-> actual phase shift 7/8,equal to HEVC MC, used for spatial scalability x2 (only for accurate Chroma alignement)
42  {  0,  4, 62, -2 }  // <-> actual phase shift 11/12, used for spatial scalability x1.5 (only for accurate Chroma alignement)
43};
44
45TComUpsampleFilter::TComUpsampleFilter(void)
46{
47}
48
49TComUpsampleFilter::~TComUpsampleFilter(void)
50{
51}
52
53Void TComUpsampleFilter::upsampleBasePic( TComSlice* currSlice, UInt refLayerIdc, TComPicYuv* pcUsPic, TComPicYuv* pcBasePic, TComPicYuv* pcTempPic, const Int refBitDepthLuma, const Int refBitDepthChroma )
54{
55  assert ( NTAPS_US_LUMA == 8 );
56  assert ( NTAPS_US_CHROMA == 4 );
57
58  Int i, j;
59
60  UInt currLayerId = currSlice->getLayerId();
61  UInt refLayerId  = currSlice->getVPS()->getRefLayerId( currLayerId, refLayerIdc );
62
63  const Window &scalEL = currSlice->getPPS()->getScaledRefLayerWindowForLayer(refLayerId);
64  const Window &windowRL = currSlice->getPPS()->getRefLayerWindowForLayer(refLayerId);
65
66  Int bitDepthLuma = currSlice->getBitDepth(CHANNEL_TYPE_LUMA);
67  Int bitDepthChroma = currSlice->getBitDepth(CHANNEL_TYPE_CHROMA);
68
69  //========== Y component upsampling ===========
70  Int widthBL   = pcBasePic->getWidth (COMPONENT_Y);
71  Int heightBL  = pcBasePic->getHeight(COMPONENT_Y);
72  Int strideBL  = pcBasePic->getStride(COMPONENT_Y);
73
74  Int widthEL   = pcUsPic->getWidth (COMPONENT_Y) - scalEL.getWindowLeftOffset() - scalEL.getWindowRightOffset();
75  Int heightEL  = pcUsPic->getHeight(COMPONENT_Y) - scalEL.getWindowTopOffset()  - scalEL.getWindowBottomOffset();
76  Int strideEL  = pcUsPic->getStride(COMPONENT_Y);
77
78  ChromaFormat chromaFormatIdc = currSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getChromaFormatIdc();
79  Int xScal = TComSPS::getWinUnitX( chromaFormatIdc );
80  Int yScal = TComSPS::getWinUnitY( chromaFormatIdc );
81
82  const ResamplingPhase &resamplingPhase = currSlice->getPPS()->getResamplingPhase( refLayerId );
83  Int phaseVerChroma = resamplingPhase.phaseVerChroma;
84
85  if( !resamplingPhase.phasePresentFlag )
86  {
87#if SCALABLE_REXT
88    if( chromaFormatIdc == CHROMA_444 )
89    {
90      phaseVerChroma = 0;
91    }
92    else
93    {
94#endif
95    Int refRegionHeight = heightBL - windowRL.getWindowTopOffset() - windowRL.getWindowBottomOffset();
96    phaseVerChroma = (4 * heightEL + (refRegionHeight >> 1)) / refRegionHeight - 4;
97#if SCALABLE_REXT
98    }
99#endif
100  }
101
102  Pel* piTempBufY = pcTempPic->getAddr(COMPONENT_Y);
103  Pel* piSrcBufY  = pcBasePic->getAddr(COMPONENT_Y);
104  Pel* piDstBufY  = pcUsPic->getAddr(COMPONENT_Y);
105
106  Pel* piSrcY;
107  Pel* piDstY;
108
109  Pel* piTempBufU = pcTempPic->getAddr(COMPONENT_Cb);
110  Pel* piSrcBufU  = pcBasePic->getAddr(COMPONENT_Cb);
111  Pel* piDstBufU  = pcUsPic->getAddr(COMPONENT_Cb);
112
113  Pel* piTempBufV = pcTempPic->getAddr(COMPONENT_Cr);
114  Pel* piSrcBufV  = pcBasePic->getAddr(COMPONENT_Cr);
115  Pel* piDstBufV  = pcUsPic->getAddr(COMPONENT_Cr);
116
117  Pel* piSrcU;
118  Pel* piDstU;
119  Pel* piSrcV;
120  Pel* piDstV;
121
122  Int scaleX = currSlice->getPic()->getPosScalingFactor(refLayerIdc, 0);
123  Int scaleY = currSlice->getPic()->getPosScalingFactor(refLayerIdc, 1);
124
125  // non-normative software optimization for certain simple resampling cases
126  if( scaleX == POS_SCALING_FACTOR_1X && scaleY == POS_SCALING_FACTOR_1X ) // ratio 1x
127  {
128    piSrcY = piSrcBufY;
129    piDstY = piDstBufY + scalEL.getWindowLeftOffset() + scalEL.getWindowTopOffset() * strideEL;
130
131    Int shift = bitDepthLuma - refBitDepthLuma;
132
133#if CGS_3D_ASYMLUT
134    if( currSlice->getPPS()->getCGSFlag() )
135    {
136      shift = bitDepthLuma - currSlice->getPPS()->getCGSOutputBitDepthY();
137    }
138#endif
139    assert( shift >= 0 );
140
141    for( i = 0; i < heightBL; i++ )
142    {
143      for( j = 0; j < widthBL; j++ )
144      {
145        piDstY[j] = piSrcY[j] << shift;
146      }
147
148      piSrcY += strideBL;
149      piDstY += strideEL;
150    }
151
152#if SCALABLE_REXT
153  if(chromaFormatIdc != 0)
154  {
155#endif
156    widthEL  >>= 1;
157    heightEL >>= 1;
158
159    widthBL  >>= 1;
160    heightBL >>= 1;
161
162    strideBL = pcBasePic->getStride( COMPONENT_Cb );
163    strideEL = pcUsPic->getStride( COMPONENT_Cb );
164
165    piSrcU = piSrcBufU;
166    piSrcV = piSrcBufV;
167
168    piDstU = piDstBufU + ( scalEL.getWindowLeftOffset() >> 1 ) + ( scalEL.getWindowTopOffset() >> 1 ) * strideEL;
169    piDstV = piDstBufV + ( scalEL.getWindowLeftOffset() >> 1 ) + ( scalEL.getWindowTopOffset() >> 1 ) * strideEL;
170
171    shift = bitDepthChroma - refBitDepthChroma;
172
173#if CGS_3D_ASYMLUT
174    if( currSlice->getPPS()->getCGSFlag() )
175    {
176      shift = bitDepthChroma - currSlice->getPPS()->getCGSOutputBitDepthC();
177    }
178#endif
179    assert( shift >= 0 );
180
181    for( i = 0; i < heightBL; i++ )
182    {
183      for( j = 0; j < widthBL; j++ )
184      {
185        piDstU[j] = piSrcU[j] << shift;
186        piDstV[j] = piSrcV[j] << shift;
187      }
188
189      piSrcU += strideBL;
190      piSrcV += strideBL;
191      piDstU += strideEL;
192      piDstV += strideEL;
193    }
194#if SCALABLE_REXT
195  }
196#endif
197  }
198  else // general resampling process
199  {
200    Int refPos16 = 0;
201    Int phase    = 0;
202    Int refPos   = 0;
203    Int* coeff = m_chromaFilter[phase];
204    for ( i = 0; i < 16; i++)
205    {
206      memcpy(   m_lumaFilter[i],   m_lumaFixedFilter[i], sizeof(Int) * NTAPS_US_LUMA   );
207      memcpy( m_chromaFilter[i], m_chromaFixedFilter[i], sizeof(Int) * NTAPS_US_CHROMA );
208    }
209
210    assert ( widthEL >= widthBL );
211    assert ( heightEL >= heightBL );
212
213    pcBasePic->setBorderExtension(false);
214    pcBasePic->extendPicBorder(); // extend the border.
215
216    Int shiftX = 16;
217    Int shiftY = 16;
218
219    Int phaseX = resamplingPhase.phaseHorLuma;
220    Int phaseY = resamplingPhase.phaseVerLuma;
221    Int addX = ( ( phaseX * scaleX + 8 ) >> 4 ) -  (1 << ( shiftX - 5 ));
222    Int addY = ( ( phaseY * scaleY + 8 ) >> 4 ) -  (1 << ( shiftX - 5 ));
223    Int refOffsetX = windowRL.getWindowLeftOffset() << 4;
224    Int refOffsetY = windowRL.getWindowTopOffset()  << 4;
225
226    Int shiftXM4 = shiftX - 4;
227    Int shiftYM4 = shiftY - 4;
228
229    widthEL  = pcUsPic->getWidth ( COMPONENT_Y );
230    heightEL = pcUsPic->getHeight( COMPONENT_Y );
231    widthBL  = pcBasePic->getWidth ( COMPONENT_Y );
232    heightBL = min<Int>( pcBasePic->getHeight( COMPONENT_Y ), heightEL );
233
234    Int phaseXL = scalEL.getWindowLeftOffset();
235    Int phaseYL = scalEL.getWindowTopOffset();
236    Int rlClipL = -(NTAPS_US_LUMA>>1);
237    Int rlClipR = widthBL -1 + (NTAPS_US_LUMA>>1);
238    Int rlClipT = -(NTAPS_US_LUMA>>1);
239    Int rlClipB = heightBL - 1 + (NTAPS_US_LUMA>>1);
240
241    // shift1 should be calculated using BL bit-depth
242    Int shift1 = refBitDepthLuma - 8;
243
244#if CGS_3D_ASYMLUT
245    if( currSlice->getPPS()->getCGSFlag() )
246    {
247      shift1 = currSlice->getPPS()->getCGSOutputBitDepthY() - 8;
248    }
249#endif
250
251    //========== horizontal upsampling ===========
252    for( i = 0; i < widthEL; i++ )
253    {
254      Int x = i;
255      refPos16 = (((x - phaseXL)*scaleX - addX) >> shiftXM4) + refOffsetX;
256      phase    = refPos16 & 15;
257      refPos   = refPos16 >> 4;
258      refPos   = Clip3( rlClipL, rlClipR, refPos );
259      coeff = m_lumaFilter[phase];
260
261      piSrcY = piSrcBufY + refPos -((NTAPS_US_LUMA>>1) - 1);
262      piDstY = piTempBufY + i;
263
264      for( j = 0; j < heightBL ; j++ )
265      {
266        *piDstY = sumLumaHor(piSrcY, coeff) >> shift1;
267        piSrcY += strideBL;
268        piDstY += strideEL;
269      }
270    }
271
272    //========== vertical upsampling ===========
273    pcTempPic->setBorderExtension(false);
274    pcTempPic->setHeight(heightBL);
275    pcTempPic->extendPicBorder   (); // extend the border.
276    pcTempPic->setHeight(heightEL);
277
278    Int nShift = 20 - bitDepthLuma;
279    Int iOffset = 1 << (nShift - 1);
280
281    for( j = 0; j < pcTempPic->getHeight(COMPONENT_Y); j++ )
282    {
283      Int y = j;
284      refPos16 = ((( y - phaseYL )*scaleY - addY) >> shiftYM4) + refOffsetY;
285      phase    = refPos16 & 15;
286      refPos   = refPos16 >> 4;
287      refPos = Clip3( rlClipT, rlClipB, refPos );
288      coeff = m_lumaFilter[phase];
289
290      piSrcY = piTempBufY + (refPos -((NTAPS_US_LUMA>>1) - 1))*strideEL;
291      Pel* piDstY0 = piDstBufY + j * strideEL;
292
293      piDstY = piDstY0;
294
295      for( i = pcTempPic->getWidth(COMPONENT_Y); i > 0; i-- )
296      {
297        *piDstY = ClipBD( (sumLumaVer(piSrcY, coeff, strideEL) + iOffset) >> (nShift), bitDepthLuma );
298        piSrcY++;
299        piDstY++;
300      }
301    }
302
303    widthBL   = pcBasePic->getWidth (COMPONENT_Y);
304    heightBL  = pcBasePic->getHeight(COMPONENT_Y);
305    widthEL   = pcUsPic->getWidth (COMPONENT_Y) - scalEL.getWindowLeftOffset() - scalEL.getWindowRightOffset();
306    heightEL  = pcUsPic->getHeight(COMPONENT_Y) - scalEL.getWindowTopOffset()  - scalEL.getWindowBottomOffset();
307
308    //========== UV component upsampling ===========
309
310#if SCALABLE_REXT
311  if(chromaFormatIdc != 0)
312  {
313#endif
314    widthEL  >>= 1;
315    heightEL >>= 1;
316    widthBL  >>= 1;
317    heightBL >>= 1;
318
319    strideBL  = pcBasePic->getStride( COMPONENT_Cb );
320    strideEL  = pcUsPic->getStride( COMPONENT_Cb );
321
322    Int srlLOffsetC = scalEL.getWindowLeftOffset() >> 1;
323    Int srlTOffsetC = scalEL.getWindowTopOffset() >> 1;
324    rlClipL = -(NTAPS_US_CHROMA>>1);
325    rlClipR = widthBL -1 + (NTAPS_US_CHROMA>>1);
326    rlClipT = -(NTAPS_US_CHROMA>>1);
327    rlClipB = heightBL - 1 + (NTAPS_US_CHROMA>>1);
328    shiftX = 16;
329    shiftY = 16;
330
331    addX = ( ( resamplingPhase.phaseHorChroma * scaleX + 8 ) >> 4 ) -  (1 << ( shiftX - 5 ));
332    addY = ( ( phaseVerChroma * scaleY + 8 ) >> 4 ) -  (1 << ( shiftX - 5 ));
333    Int refOffsetXC = (windowRL.getWindowLeftOffset() / xScal) << 4;
334    Int refOffsetYC = (windowRL.getWindowTopOffset()  / yScal) << 4;
335
336    shiftXM4 = shiftX - 4;
337    shiftYM4 = shiftY - 4;
338
339    widthEL   = pcUsPic->getWidth (COMPONENT_Y) >> 1;
340    heightEL  = pcUsPic->getHeight(COMPONENT_Y) >> 1;
341
342    widthBL   = pcBasePic->getWidth (COMPONENT_Y) >> 1;
343    heightBL  = min<Int>( pcBasePic->getHeight(COMPONENT_Y) >> 1, heightEL );
344
345    // shift1 should be calculated using BL bit-depth
346    shift1 = refBitDepthChroma - 8;
347
348#if CGS_3D_ASYMLUT
349    if( currSlice->getPPS()->getCGSFlag() )
350    {
351      shift1 = currSlice->getPPS()->getCGSOutputBitDepthC() - 8;
352    }
353#endif
354
355    //========== horizontal upsampling ===========
356    for( i = 0; i < widthEL; i++ )
357    {
358      Int x = i;
359      refPos16 = (((x - srlLOffsetC)*scaleX - addX) >> shiftXM4) + refOffsetXC;
360      phase    = refPos16 & 15;
361      refPos   = refPos16 >> 4;
362      refPos   = Clip3(rlClipL, rlClipR, refPos);
363      coeff = m_chromaFilter[phase];
364
365      piSrcU = piSrcBufU + refPos -((NTAPS_US_CHROMA>>1) - 1);
366      piSrcV = piSrcBufV + refPos -((NTAPS_US_CHROMA>>1) - 1);
367      piDstU = piTempBufU + i;
368      piDstV = piTempBufV + i;
369
370      for( j = 0; j < heightBL ; j++ )
371      {
372        *piDstU = sumChromaHor(piSrcU, coeff) >> shift1;
373        *piDstV = sumChromaHor(piSrcV, coeff) >> shift1;
374
375        piSrcU += strideBL;
376        piSrcV += strideBL;
377        piDstU += strideEL;
378        piDstV += strideEL;
379      }
380    }
381
382    //========== vertical upsampling ===========
383    pcTempPic->setBorderExtension(false);
384    pcTempPic->setHeight(heightBL << 1);
385    pcTempPic->extendPicBorder   (); // extend the border.
386    pcTempPic->setHeight(heightEL << 1);
387
388    nShift = 20 - bitDepthChroma;
389
390    iOffset = 1 << (nShift - 1);
391
392    for( j = 0; j < pcTempPic->getHeight(COMPONENT_Y) >> 1; j++ )
393    {
394      Int y = j;
395      refPos16 = (((y - srlTOffsetC)*scaleY - addY) >> shiftYM4) + refOffsetYC;
396      phase    = refPos16 & 15;
397      refPos   = refPos16 >> 4;
398      refPos = Clip3(rlClipT, rlClipB, refPos);
399      coeff = m_chromaFilter[phase];
400
401      piSrcU = piTempBufU  + (refPos -((NTAPS_US_CHROMA>>1) - 1))*strideEL;
402      piSrcV = piTempBufV  + (refPos -((NTAPS_US_CHROMA>>1) - 1))*strideEL;
403
404      Pel* piDstU0 = piDstBufU + j*strideEL;
405      Pel* piDstV0 = piDstBufV + j*strideEL;
406
407      piDstU = piDstU0;
408      piDstV = piDstV0;
409
410      for( i = pcTempPic->getWidth(COMPONENT_Y) >> 1; i > 0; i-- )
411      {
412        *piDstU = ClipBD( (sumChromaVer(piSrcU, coeff, strideEL) + iOffset) >> (nShift), bitDepthChroma );
413        *piDstV = ClipBD( (sumChromaVer(piSrcV, coeff, strideEL) + iOffset) >> (nShift), bitDepthChroma );
414        piSrcU++;
415        piSrcV++;
416        piDstU++;
417        piDstV++;
418      }
419    }
420#if SCALABLE_REXT
421    }
422#endif
423  }
424    pcUsPic->setBorderExtension(false);
425    pcUsPic->extendPicBorder   (); // extend the border.
426
427    //Reset the Border extension flag
428    pcUsPic->setBorderExtension(false);
429    pcTempPic->setBorderExtension(false);
430    pcBasePic->setBorderExtension(false);
431}
432#endif //SVC_EXTENSION
Note: See TracBrowser for help on using the repository browser.