📄 downconverttools.inl
字号:
Tmp1dBufferInQ1pel[iInLength-1] = ( (m_paiTmp1dBuffer[iInLength-1]<<5) + Tmp1dBufferInHalfpel[iInLength-1] + 1) >> 1;
Tmp1dBufferInQ3pel[iInLength-1] = Tmp1dBufferInHalfpel[iInLength-1] ;
// generic interpolation to nearest 1/4 pel position
for (int iout=0; iout<iOutLength; iout++)
{
double dpos0 = ((double)iout * iInLength / iOutLength);
int ipos0 = (int)dpos0;
double rpos0 = dpos0 - ipos0;
int iIndex = (int) (8 * rpos0);
switch (iIndex)
{
case 0:
m_paiTmp1dBufferOut[iout] = m_paiTmp1dBuffer[ipos0] << 5; // original pel value
break;
case 1:
case 2:
m_paiTmp1dBufferOut[iout] = Tmp1dBufferInQ1pel[ipos0]; // 1/4 pel value
break;
case 3:
case 4:
m_paiTmp1dBufferOut[iout] = Tmp1dBufferInHalfpel[ipos0]; // half pel value
break;
case 5:
case 6:
m_paiTmp1dBufferOut[iout] = Tmp1dBufferInQ3pel[ipos0]; // 1/4 pel value
break;
case 7:
int ipos1 = (ipos0+1 < iInLength) ? ipos0+1 : ipos0;
m_paiTmp1dBufferOut[iout] = m_paiTmp1dBuffer[ipos1] << 5; // original pel value
break;
}
}
}
// =================================================================================
// INTRA 1 Lanczos
// =================================================================================
#define TMM_TABLE_SIZE 512
#define TMM_FILTER_WINDOW_SIZE 3
#define NFACT 12
#define VALFACT (1l<<NFACT)
#define MASKFACT (VALFACT-1)
//*************************************************************************
// lanczos filter coeffs computation
__inline
void
DownConvert::xInitFilterTmm1 ()
{
xDestroyFilterTmm1();
const double pi = 3.14159265359;
m_padFilter = new long[TMM_TABLE_SIZE];
m_padFilter[0] = VALFACT;
for (int i=1; i<TMM_TABLE_SIZE; i++)
{
double x = ((double)i/TMM_TABLE_SIZE) * TMM_FILTER_WINDOW_SIZE;
double pix = pi*x;
double pixw = pix/TMM_FILTER_WINDOW_SIZE;
m_padFilter[i] = (long)(sin(pix)/pix * sin(pixw)/pixw * VALFACT);
}
}
__inline
void
DownConvert::xDestroyFilterTmm1 ( )
{
if(m_padFilter)
{
delete [] m_padFilter;
m_padFilter=NULL;
}
}
//*************************************************************************
__inline
void
DownConvert::xUpsampling1( ResizeParameters* pcParameters,
bool bLuma)
{
int iInWidth = pcParameters->m_iInWidth;
int iInHeight = pcParameters->m_iInHeight;
int iOutWidth = pcParameters->m_iOutWidth;
int iOutHeight = pcParameters->m_iOutHeight;
if (!bLuma)
{
iInWidth >>= 1;
iInHeight >>= 1;
iOutWidth >>= 1;
iOutHeight >>= 1;
}
int iNumerator = 1;
int iDenominator = 1;
long spos;
// ===== vertical upsampling =====
xComputeNumeratorDenominator(iInHeight,iOutHeight,&iNumerator,&iDenominator);
spos = (1<<NFACT) * iDenominator / iNumerator;
for (int xin=0; xin<iInWidth; xin++)
{
int* piSrc = &m_paiImageBuffer[xin];
for (int yin=0; yin<iInHeight; yin++)
m_paiTmp1dBuffer[yin] = piSrc[yin * m_iImageStride];
xUpsamplingData1(iInHeight, iOutHeight, spos);
for(int yout = 0; yout < iOutHeight; yout++ )
piSrc[yout*m_iImageStride] = m_paiTmp1dBufferOut[yout];
}
// ===== horizontal upsampling =====
xComputeNumeratorDenominator(iInWidth,iOutWidth,&iNumerator,&iDenominator);
spos = (1<<NFACT) * iDenominator / iNumerator;
for (int yout=0; yout<iOutHeight; yout++)
{
int* piSrc = &m_paiImageBuffer[yout * m_iImageStride];
for (int xin=0; xin<iInWidth; xin++)
m_paiTmp1dBuffer[xin] = piSrc[xin];
xUpsamplingData1(iInWidth, iOutWidth, spos);
memcpy(piSrc, m_paiTmp1dBufferOut, iOutWidth*sizeof(int));
}
}
__inline
void
DownConvert::xUpsamplingData1 ( int iInLength , int iOutLength , long spos )
{
long dpos0 = -spos;
for (int iout=0; iout<iOutLength; iout++)
{
dpos0 += spos;
long rpos0 = dpos0 & MASKFACT;
int ipos0 = dpos0 >> NFACT;
if (rpos0 == 0) {
m_paiTmp1dBufferOut[iout] = m_paiTmp1dBuffer[ipos0];
continue;
}
int end = ipos0 + TMM_FILTER_WINDOW_SIZE;
int begin = end - TMM_FILTER_WINDOW_SIZE*2;
long sval = 0;
long posi = ((begin-ipos0)<<NFACT) - rpos0;
for (int i=begin; i<=end; i++, posi += VALFACT)
{
long fact = xGetFilter(posi);
int val;
if (i<0) val = m_paiTmp1dBuffer[0];
else if (i>=iInLength) val = m_paiTmp1dBuffer[iInLength-1];
else val = m_paiTmp1dBuffer[i];
sval += val * fact;
}
m_paiTmp1dBufferOut[iout] = sval>>NFACT;
}
}
__inline
void
DownConvert::xComputeNumeratorDenominator ( int iInWidth , int iOutWidth ,
int* iNumerator, int *iDenominator)
{
int iA = 1;
int iB = iOutWidth;
int iC = iInWidth;
while (iC != 0)
{
iA = iB;
iB = iC;
iC = iA % iB;
}
*iNumerator = iOutWidth / iB;
*iDenominator = iInWidth / iB;
}
__inline
long
DownConvert::xGetFilter ( long x )
{
x = abs(x);
int ind = (int)((x / TMM_FILTER_WINDOW_SIZE) * TMM_TABLE_SIZE) >> NFACT;
if (ind >= TMM_TABLE_SIZE) return 0;
return m_padFilter[ind];
}
__inline
void
DownConvert::upsample_ver( unsigned char* pucBufferY, int iStrideY,
unsigned char* pucBufferU, int iStrideU,
unsigned char* pucBufferV, int iStrideV,
int iWidth, int iHeight,
int iPosY, int iCropY,
bool top_flg )
{
//===== luma =====
#if UPS4TAP
FILTER_UP_4
#else
FILTER_UP
#endif
xCopyToImageBuffer ( pucBufferY, iWidth, iHeight, iWidth );
xUpsampling_ver ( iWidth, iHeight, iPosY, iCropY, piFilter, top_flg );
xCopyFromImageBuffer( pucBufferY, iWidth, iHeight*2, iWidth, 0, 255 );
FILTER_UP_CHROMA
//===== chroma cb =====
xCopyToImageBuffer ( pucBufferU, iWidth/2, iHeight/2, iWidth/2 );
xUpsampling_ver ( iWidth/2, iHeight/2, iPosY/2, iCropY/2, piFilter_chroma, top_flg );
xCopyFromImageBuffer( pucBufferU, iWidth/2, iHeight, iWidth/2, 0, 255 );
//===== chroma cr =====
xCopyToImageBuffer ( pucBufferV, iWidth/2, iHeight/2, iWidth/2 );
xUpsampling_ver ( iWidth/2, iHeight/2, iPosY/2, iCropY/2, piFilter_chroma, top_flg );
xCopyFromImageBuffer( pucBufferV, iWidth/2, iHeight, iWidth/2, 0, 255 );
}
__inline
void
DownConvert::upsample_ver( short* psBufferY, int iStrideY,
short* psBufferU, int iStrideU,
short* psBufferV, int iStrideV,
int iWidth, int iHeight,
int iPosY, int iCropY,
bool bClip, bool top_flg )
{
#if UPS4TAP
FILTER_UP_4
#else
FILTER_UP
#endif
if(!bClip){
for(int i=0; i<15; i++)piFilter[i]=0;
piFilter[7]=2; piFilter[6]=piFilter[8]=1; piFilter[15]=4;
}
int imin = ( bClip ? 0 : -32768 );
int imax = ( bClip ? 255 : 32767 );
//===== luma =====
xCopyToImageBuffer ( psBufferY, iWidth, iHeight, iStrideY );
xUpsampling_ver ( iWidth, iHeight, iPosY, iCropY, piFilter, top_flg );
xCopyFromImageBuffer( psBufferY, iWidth, iHeight*2, iStrideY, imin, imax );
//===== chroma cb =====
xCopyToImageBuffer ( psBufferU, iWidth/2, iHeight/2, iStrideU );
xUpsampling_ver ( iWidth/2, iHeight/2, iPosY/2, iCropY/2, piFilter, top_flg );
xCopyFromImageBuffer( psBufferU, iWidth/2, iHeight, iStrideU, imin, imax );
//===== chroma cr =====
xCopyToImageBuffer ( psBufferV, iWidth/2, iHeight/2, iStrideV );
xUpsampling_ver ( iWidth/2, iHeight/2, iPosY/2, iCropY/2, piFilter, top_flg );
xCopyFromImageBuffer( psBufferV, iWidth/2, iHeight, iStrideV, imin, imax );
}
__inline
void
DownConvert::upsample3( unsigned char* pucBufferY, unsigned char* pucBufferU, unsigned char* pucBufferV,
int input_width, int input_height, int output_width, int output_height,
int crop_x0, int crop_y0, int crop_w, int crop_h,
int input_chroma_phase_shift_x, int input_chroma_phase_shift_y,
int output_chroma_phase_shift_x, int output_chroma_phase_shift_y,
int resample_mode, int buf_size )
{
int top;
if(resample_mode==1 || resample_mode>3)
{
input_height >>= 1;
top = (resample_mode==1 || resample_mode==4 || resample_mode==7);
input_chroma_phase_shift_y = input_chroma_phase_shift_y + 1 - 2*top;
}
else
input_chroma_phase_shift_y *= 2;
input_chroma_phase_shift_x *= 2;
if(resample_mode>0)
{
crop_y0 >>= 1;
crop_h >>= 1;
output_height >>= 1;
top = (resample_mode==1 || resample_mode==2 || resample_mode==4 || resample_mode==7);
output_chroma_phase_shift_y = output_chroma_phase_shift_y + 1 - 2*top;
}
else
output_chroma_phase_shift_y *= 2;
output_chroma_phase_shift_x *= 2;
for(int loop=0; loop<2; loop++){
//===== luma =====
xCopyToImageBuffer ( pucBufferY, input_width, input_height, input_width );
xUpsampling3 ( input_width, input_height, output_width, output_height,
crop_x0, crop_y0, crop_w, crop_h, 0, 0, 0, 0, 0 );
xCopyFromImageBuffer( pucBufferY, output_width, output_height, output_width, 0, 255 );
//===== chroma cb =====
xCopyToImageBuffer ( pucBufferU, input_width/2, input_height/2, input_width/2 );
xUpsampling3 ( input_width/2, input_height/2, output_width/2, output_height/2,
crop_x0/2, crop_y0/2, crop_w/2, crop_h/2,
input_chroma_phase_shift_x, input_chroma_phase_shift_y,
output_chroma_phase_shift_x, output_chroma_phase_shift_y, 1 );
xCopyFromImageBuffer( pucBufferU, output_width/2, output_height/2, output_width/2, 0, 255 );
//===== chroma cr =====
xCopyToImageBuffer ( pucBufferV, input_width/2, input_height/2, input_width/2 );
xUpsampling3 ( input_width/2, input_height/2, output_width/2, output_height/2,
crop_x0/2, crop_y0/2, crop_w/2, crop_h/2,
input_chroma_phase_shift_x, input_chroma_phase_shift_y,
output_chroma_phase_shift_x, output_chroma_phase_shift_y, 1 );
xCopyFromImageBuffer( pucBufferV, output_width/2, output_height/2, output_width/2, 0, 255 );
if(resample_mode==1){
input_chroma_phase_shift_y += 2;
output_chroma_phase_shift_y += 2;
pucBufferY += buf_size;
pucBufferU += buf_size/4;
pucBufferV += buf_size/4;
}
else loop++;
}
}
#undef NFACT
#undef VALFACT
#undef MASKFACT
#undef TMM_TABLE_SIZE
#undef TMM_FILTER_WINDOW_SIZE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -