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

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

remove VPS member from picture

  • Property svn:eol-style set to native
File size: 16.1 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->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
67  Int bitDepthChroma = currSlice->getSPS()->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)->getSPS()->getChromaFormatIdc();
79#if SCALABLE_REXT
80  Int chromaHorScalingEL = TComSPS::getWinUnitX( currSlice->getSPS()->getChromaFormatIdc() );
81  Int chromaVerScalingEL = TComSPS::getWinUnitY( currSlice->getSPS()->getChromaFormatIdc() );
82
83  Int chromaHorScalingBL = TComSPS::getWinUnitX( chromaFormatIdc );
84  Int chromaVerScalingBL = TComSPS::getWinUnitY( chromaFormatIdc );
85#else
86  Int xScal = TComSPS::getWinUnitX( chromaFormatIdc );
87  Int yScal = TComSPS::getWinUnitY( chromaFormatIdc );
88#endif
89
90  const ResamplingPhase &resamplingPhase = currSlice->getPPS()->getResamplingPhase( refLayerId );
91  Int phaseVerChroma = resamplingPhase.phaseVerChroma;
92
93  if( !resamplingPhase.phasePresentFlag )
94  {
95#if SCALABLE_REXT
96    if( chromaFormatIdc == CHROMA_444 )
97    {
98      phaseVerChroma = 0;
99    }
100    else
101    {
102#endif
103    Int refRegionHeight = heightBL - windowRL.getWindowTopOffset() - windowRL.getWindowBottomOffset();
104    phaseVerChroma = (4 * heightEL + (refRegionHeight >> 1)) / refRegionHeight - 4;
105#if SCALABLE_REXT
106    }
107#endif
108  }
109
110  Pel* piTempBufY = pcTempPic->getAddr(COMPONENT_Y);
111  Pel* piSrcBufY  = pcBasePic->getAddr(COMPONENT_Y);
112  Pel* piDstBufY  = pcUsPic->getAddr(COMPONENT_Y);
113
114  Pel* piSrcY;
115  Pel* piDstY;
116
117  Pel* piTempBufU = pcTempPic->getAddr(COMPONENT_Cb);
118  Pel* piSrcBufU  = pcBasePic->getAddr(COMPONENT_Cb);
119  Pel* piDstBufU  = pcUsPic->getAddr(COMPONENT_Cb);
120
121  Pel* piTempBufV = pcTempPic->getAddr(COMPONENT_Cr);
122  Pel* piSrcBufV  = pcBasePic->getAddr(COMPONENT_Cr);
123  Pel* piDstBufV  = pcUsPic->getAddr(COMPONENT_Cr);
124
125  Pel* piSrcU;
126  Pel* piDstU;
127  Pel* piSrcV;
128  Pel* piDstV;
129
130  Int scaleX = currSlice->getPic()->getPosScalingFactor(refLayerIdc, 0);
131  Int scaleY = currSlice->getPic()->getPosScalingFactor(refLayerIdc, 1);
132
133  // non-normative software optimization for certain simple resampling cases
134  if( scaleX == POS_SCALING_FACTOR_1X && scaleY == POS_SCALING_FACTOR_1X ) // ratio 1x
135  {
136    piSrcY = piSrcBufY;
137    piDstY = piDstBufY + scalEL.getWindowLeftOffset() + scalEL.getWindowTopOffset() * strideEL;
138
139    Int shift = bitDepthLuma - refBitDepthLuma;
140
141#if CGS_3D_ASYMLUT
142    if( currSlice->getPPS()->getCGSFlag() )
143    {
144      shift = bitDepthLuma - currSlice->getPPS()->getCGSOutputBitDepthY();
145    }
146#endif
147    assert( shift >= 0 );
148
149    for( i = 0; i < heightBL; i++ )
150    {
151      for( j = 0; j < widthBL; j++ )
152      {
153        piDstY[j] = piSrcY[j] << shift;
154      }
155
156      piSrcY += strideBL;
157      piDstY += strideEL;
158    }
159
160#if SCALABLE_REXT
161  if( chromaFormatIdc != CHROMA_400 )
162  {
163    widthEL  /= chromaHorScalingEL;
164    heightEL /= chromaVerScalingEL;
165    widthBL  /= chromaHorScalingBL;
166    heightBL /= chromaVerScalingBL;
167#else
168    widthEL  >>= 1;
169    heightEL >>= 1;
170
171    widthBL  >>= 1;
172    heightBL >>= 1;
173#endif
174
175    strideBL = pcBasePic->getStride( COMPONENT_Cb );
176    strideEL = pcUsPic->getStride( COMPONENT_Cb );
177
178    piSrcU = piSrcBufU;
179    piSrcV = piSrcBufV;
180
181#if SCALABLE_REXT
182    piDstU = piDstBufU + ( scalEL.getWindowLeftOffset() / chromaHorScalingEL ) + ( scalEL.getWindowTopOffset() / chromaVerScalingEL ) * strideEL;
183    piDstV = piDstBufV + ( scalEL.getWindowLeftOffset() / chromaHorScalingEL ) + ( scalEL.getWindowTopOffset() / chromaVerScalingEL ) * strideEL;
184#else
185    piDstU = piDstBufU + ( scalEL.getWindowLeftOffset() >> 1 ) + ( scalEL.getWindowTopOffset() >> 1 ) * strideEL;
186    piDstV = piDstBufV + ( scalEL.getWindowLeftOffset() >> 1 ) + ( scalEL.getWindowTopOffset() >> 1 ) * strideEL;
187#endif
188
189    shift = bitDepthChroma - refBitDepthChroma;
190
191#if CGS_3D_ASYMLUT
192    if( currSlice->getPPS()->getCGSFlag() )
193    {
194      shift = bitDepthChroma - currSlice->getPPS()->getCGSOutputBitDepthC();
195    }
196#endif
197    assert( shift >= 0 );
198
199    for( i = 0; i < heightBL; i++ )
200    {
201      for( j = 0; j < widthBL; j++ )
202      {
203        piDstU[j] = piSrcU[j] << shift;
204        piDstV[j] = piSrcV[j] << shift;
205      }
206
207      piSrcU += strideBL;
208      piSrcV += strideBL;
209      piDstU += strideEL;
210      piDstV += strideEL;
211    }
212#if SCALABLE_REXT
213  }
214#endif
215  }
216  else // general resampling process
217  {
218    Int refPos16 = 0;
219    Int phase    = 0;
220    Int refPos   = 0;
221    Int* coeff = m_chromaFilter[phase];
222    for ( i = 0; i < 16; i++)
223    {
224      memcpy(   m_lumaFilter[i],   m_lumaFixedFilter[i], sizeof(Int) * NTAPS_US_LUMA   );
225      memcpy( m_chromaFilter[i], m_chromaFixedFilter[i], sizeof(Int) * NTAPS_US_CHROMA );
226    }
227
228    assert ( widthEL >= widthBL );
229    assert ( heightEL >= heightBL );
230
231    pcBasePic->setBorderExtension(false);
232    pcBasePic->extendPicBorder(); // extend the border.
233
234    Int shiftX = 16;
235    Int shiftY = 16;
236
237    Int phaseX = resamplingPhase.phaseHorLuma;
238    Int phaseY = resamplingPhase.phaseVerLuma;
239    Int addX = ( ( phaseX * scaleX + 8 ) >> 4 ) -  (1 << ( shiftX - 5 ));
240    Int addY = ( ( phaseY * scaleY + 8 ) >> 4 ) -  (1 << ( shiftX - 5 ));
241    Int refOffsetX = windowRL.getWindowLeftOffset() << 4;
242    Int refOffsetY = windowRL.getWindowTopOffset()  << 4;
243
244    Int shiftXM4 = shiftX - 4;
245    Int shiftYM4 = shiftY - 4;
246
247    widthEL  = pcUsPic->getWidth ( COMPONENT_Y );
248    heightEL = pcUsPic->getHeight( COMPONENT_Y );
249    widthBL  = pcBasePic->getWidth ( COMPONENT_Y );
250    heightBL = min<Int>( pcBasePic->getHeight( COMPONENT_Y ), heightEL );
251
252    Int phaseXL = scalEL.getWindowLeftOffset();
253    Int phaseYL = scalEL.getWindowTopOffset();
254    Int rlClipL = -(NTAPS_US_LUMA>>1);
255    Int rlClipR = widthBL -1 + (NTAPS_US_LUMA>>1);
256    Int rlClipT = -(NTAPS_US_LUMA>>1);
257    Int rlClipB = heightBL - 1 + (NTAPS_US_LUMA>>1);
258
259    // shift1 should be calculated using BL bit-depth
260    Int shift1 = refBitDepthLuma - 8;
261
262#if CGS_3D_ASYMLUT
263    if( currSlice->getPPS()->getCGSFlag() )
264    {
265      shift1 = currSlice->getPPS()->getCGSOutputBitDepthY() - 8;
266    }
267#endif
268
269    //========== horizontal upsampling ===========
270    for( i = 0; i < widthEL; i++ )
271    {
272      Int x = i;
273      refPos16 = (((x - phaseXL)*scaleX - addX) >> shiftXM4) + refOffsetX;
274      phase    = refPos16 & 15;
275      refPos   = refPos16 >> 4;
276      refPos   = Clip3( rlClipL, rlClipR, refPos );
277      coeff = m_lumaFilter[phase];
278
279      piSrcY = piSrcBufY + refPos -((NTAPS_US_LUMA>>1) - 1);
280      piDstY = piTempBufY + i;
281
282      for( j = 0; j < heightBL ; j++ )
283      {
284        *piDstY = sumLumaHor(piSrcY, coeff) >> shift1;
285        piSrcY += strideBL;
286        piDstY += strideEL;
287      }
288    }
289
290    //========== vertical upsampling ===========
291    pcTempPic->setBorderExtension(false);
292    pcTempPic->setHeight(heightBL);
293    pcTempPic->extendPicBorder   (); // extend the border.
294    pcTempPic->setHeight(heightEL);
295
296    Int nShift = 20 - bitDepthLuma;
297    Int iOffset = 1 << (nShift - 1);
298
299    for( j = 0; j < pcTempPic->getHeight(COMPONENT_Y); j++ )
300    {
301      Int y = j;
302      refPos16 = ((( y - phaseYL )*scaleY - addY) >> shiftYM4) + refOffsetY;
303      phase    = refPos16 & 15;
304      refPos   = refPos16 >> 4;
305      refPos = Clip3( rlClipT, rlClipB, refPos );
306      coeff = m_lumaFilter[phase];
307
308      piSrcY = piTempBufY + (refPos -((NTAPS_US_LUMA>>1) - 1))*strideEL;
309      Pel* piDstY0 = piDstBufY + j * strideEL;
310
311      piDstY = piDstY0;
312
313      for( i = pcTempPic->getWidth(COMPONENT_Y); i > 0; i-- )
314      {
315        *piDstY = ClipBD( (sumLumaVer(piSrcY, coeff, strideEL) + iOffset) >> (nShift), bitDepthLuma );
316        piSrcY++;
317        piDstY++;
318      }
319    }
320
321    widthBL   = pcBasePic->getWidth (COMPONENT_Y);
322    heightBL  = pcBasePic->getHeight(COMPONENT_Y);
323    widthEL   = pcUsPic->getWidth (COMPONENT_Y) - scalEL.getWindowLeftOffset() - scalEL.getWindowRightOffset();
324    heightEL  = pcUsPic->getHeight(COMPONENT_Y) - scalEL.getWindowTopOffset()  - scalEL.getWindowBottomOffset();
325
326    //========== UV component upsampling ===========
327
328#if SCALABLE_REXT
329  if( chromaFormatIdc != CHROMA_400 )
330  {
331    widthEL  /= chromaHorScalingEL;
332    heightEL /= chromaVerScalingEL;
333    widthBL  /= chromaHorScalingBL;
334    heightBL /= chromaVerScalingBL;
335#else
336    widthEL  >>= 1;
337    heightEL >>= 1;
338    widthBL  >>= 1;
339    heightBL >>= 1;
340#endif
341
342    strideBL  = pcBasePic->getStride( COMPONENT_Cb );
343    strideEL  = pcUsPic->getStride( COMPONENT_Cb );
344
345#if SCALABLE_REXT
346    Int srlLOffsetC = scalEL.getWindowLeftOffset() / chromaHorScalingEL;
347    Int srlTOffsetC = scalEL.getWindowTopOffset() / chromaVerScalingEL;
348#else
349    Int srlLOffsetC = scalEL.getWindowLeftOffset() >> 1;
350    Int srlTOffsetC = scalEL.getWindowTopOffset() >> 1;
351#endif
352
353    rlClipL = -(NTAPS_US_CHROMA>>1);
354    rlClipR = widthBL -1 + (NTAPS_US_CHROMA>>1);
355    rlClipT = -(NTAPS_US_CHROMA>>1);
356    rlClipB = heightBL - 1 + (NTAPS_US_CHROMA>>1);
357    shiftX = 16;
358    shiftY = 16;
359
360    addX = ( ( resamplingPhase.phaseHorChroma * scaleX + 8 ) >> 4 ) -  (1 << ( shiftX - 5 ));
361    addY = ( ( phaseVerChroma * scaleY + 8 ) >> 4 ) -  (1 << ( shiftX - 5 ));
362
363#if SCALABLE_REXT
364    Int refOffsetXC = (windowRL.getWindowLeftOffset() / chromaHorScalingBL) << 4;
365    Int refOffsetYC = (windowRL.getWindowTopOffset()  / chromaVerScalingBL) << 4;
366#else
367    Int refOffsetXC = (windowRL.getWindowLeftOffset() / xScal) << 4;
368    Int refOffsetYC = (windowRL.getWindowTopOffset()  / yScal) << 4;
369#endif
370
371    shiftXM4 = shiftX - 4;
372    shiftYM4 = shiftY - 4;
373
374#if SCALABLE_REXT
375    widthEL   = pcUsPic->getWidth (COMPONENT_Y) / chromaHorScalingEL;
376    heightEL  = pcUsPic->getHeight(COMPONENT_Y) / chromaVerScalingEL;
377
378    widthBL   = pcBasePic->getWidth (COMPONENT_Y) / chromaHorScalingBL;
379    heightBL  = min<Int>( pcBasePic->getHeight(COMPONENT_Y) / chromaVerScalingBL, heightEL );
380#else
381    widthEL   = pcUsPic->getWidth (COMPONENT_Y) >> 1;
382    heightEL  = pcUsPic->getHeight(COMPONENT_Y) >> 1;
383
384    widthBL   = pcBasePic->getWidth (COMPONENT_Y) >> 1;
385    heightBL  = min<Int>( pcBasePic->getHeight(COMPONENT_Y) >> 1, heightEL );
386#endif
387
388    // shift1 should be calculated using BL bit-depth
389    shift1 = refBitDepthChroma - 8;
390
391#if CGS_3D_ASYMLUT
392    if( currSlice->getPPS()->getCGSFlag() )
393    {
394      shift1 = currSlice->getPPS()->getCGSOutputBitDepthC() - 8;
395    }
396#endif
397
398    //========== horizontal upsampling ===========
399    for( i = 0; i < widthEL; i++ )
400    {
401      Int x = i;
402      refPos16 = (((x - srlLOffsetC)*scaleX - addX) >> shiftXM4) + refOffsetXC;
403      phase    = refPos16 & 15;
404      refPos   = refPos16 >> 4;
405      refPos   = Clip3(rlClipL, rlClipR, refPos);
406      coeff = m_chromaFilter[phase];
407
408      piSrcU = piSrcBufU + refPos -((NTAPS_US_CHROMA>>1) - 1);
409      piSrcV = piSrcBufV + refPos -((NTAPS_US_CHROMA>>1) - 1);
410      piDstU = piTempBufU + i;
411      piDstV = piTempBufV + i;
412
413      for( j = 0; j < heightBL ; j++ )
414      {
415        *piDstU = sumChromaHor(piSrcU, coeff) >> shift1;
416        *piDstV = sumChromaHor(piSrcV, coeff) >> shift1;
417
418        piSrcU += strideBL;
419        piSrcV += strideBL;
420        piDstU += strideEL;
421        piDstV += strideEL;
422      }
423    }
424
425    //========== vertical upsampling ===========
426    pcTempPic->setBorderExtension(false);
427#if SCALABLE_REXT
428    pcTempPic->setHeight(heightBL * chromaVerScalingBL);
429#else
430    pcTempPic->setHeight(heightBL << 1);
431#endif
432    pcTempPic->extendPicBorder(); // extend the border.
433#if SCALABLE_REXT
434    pcTempPic->setHeight(heightEL * chromaVerScalingEL);
435#else
436    pcTempPic->setHeight(heightEL << 1);
437#endif
438
439    nShift = 20 - bitDepthChroma;
440
441    iOffset = 1 << (nShift - 1);
442
443#if SCALABLE_REXT
444    for( j = 0; j < pcTempPic->getHeight(COMPONENT_Y) / chromaVerScalingEL; j++ )
445#else
446    for( j = 0; j < pcTempPic->getHeight(COMPONENT_Y) >> 1; j++ )
447#endif
448    {
449      Int y = j;
450      refPos16 = (((y - srlTOffsetC)*scaleY - addY) >> shiftYM4) + refOffsetYC;
451      phase    = refPos16 & 15;
452      refPos   = refPos16 >> 4;
453      refPos = Clip3(rlClipT, rlClipB, refPos);
454      coeff = m_chromaFilter[phase];
455
456      piSrcU = piTempBufU  + (refPos -((NTAPS_US_CHROMA>>1) - 1))*strideEL;
457      piSrcV = piTempBufV  + (refPos -((NTAPS_US_CHROMA>>1) - 1))*strideEL;
458
459      Pel* piDstU0 = piDstBufU + j*strideEL;
460      Pel* piDstV0 = piDstBufV + j*strideEL;
461
462      piDstU = piDstU0;
463      piDstV = piDstV0;
464
465#if SCALABLE_REXT
466      for( i = pcTempPic->getWidth(COMPONENT_Y) / chromaHorScalingEL; i > 0; i-- )
467#else
468      for( i = pcTempPic->getWidth(COMPONENT_Y) >> 1; i > 0; i-- )
469#endif
470      {
471        *piDstU = ClipBD( (sumChromaVer(piSrcU, coeff, strideEL) + iOffset) >> (nShift), bitDepthChroma );
472        *piDstV = ClipBD( (sumChromaVer(piSrcV, coeff, strideEL) + iOffset) >> (nShift), bitDepthChroma );
473        piSrcU++;
474        piSrcV++;
475        piDstU++;
476        piDstV++;
477      }
478    }
479#if SCALABLE_REXT
480    }
481#endif
482  }
483    pcUsPic->setBorderExtension(false);
484    pcUsPic->extendPicBorder   (); // extend the border.
485
486    //Reset the Border extension flag
487    pcUsPic->setBorderExtension(false);
488    pcTempPic->setBorderExtension(false);
489    pcBasePic->setBorderExtension(false);
490}
491#endif //SVC_EXTENSION
Note: See TracBrowser for help on using the repository browser.