📄 image.c
字号:
{
for( j = 0; j < BLOCK_SIZE; j++ )
for( i = 0; i < BLOCK_SIZE; i++ )
block[i][j] = Clip3(0, img->max_imgpel_value, ( tmp[j][i+3] + rounding2 ) >> shifting2 );
}
else
{
for( j = 0; j < BLOCK_SIZE; j++ )
for( i = 0; i < BLOCK_SIZE; i++ )
{
for( result = 0, x = -3; x < 5; x++ )
result += tmp[j][i+x+3] * COEF[(dx>>1)-1][x+3];
block[i][j] = Clip3(0, img->max_imgpel_value, ( result + 32768 ) >> 16 );
}
}
// right 1/4-pel position for averaging
if (dx == 7)
{
for( j = 0; j < BLOCK_SIZE; j++ )
for( i = 0; i < BLOCK_SIZE; i++ )
block2[i][j] = Clip3(0, img->max_imgpel_value, ( tmp[j][i+4] + rounding2 ) >> shifting2 );
}
else
{
for( j = 0; j < BLOCK_SIZE; j++ )
for( i = 0; i < BLOCK_SIZE; i++ )
{
for( result = 0, x = -3; x < 5; x++ )
result += tmp[j][i+x+3] * COEF[dx>>1][x+3];
block2[i][j] = Clip3(0, img->max_imgpel_value, ( result + 32768 ) >> 16 );
}
}
average_block( block, block2 );
}
else
{ // 1/8-1/8 positions
int block3[BLOCK_SIZE][BLOCK_SIZE];
int block4[BLOCK_SIZE][BLOCK_SIZE];
if( dy == 1 || dy == 7 )
{ // upper and lower egde of one block
if( dx == 1 || dx == 7 )
{ // full-pel in reach, two positions at the edge
get_fullpel_block( ref_frame, list, pres_x+(dx==7), pres_y+(dy==7), max_x, max_y, block );
interp_block_X ( ref_frame, list, pres_x, pres_y+(dy==7), COEF[dx==1?0:2], max_x, max_y, block2 );
interp_block_Y ( ref_frame, list, pres_x+(dx==7), pres_y, COEF[dy==1?0:2], max_x, max_y, block3 );
interp_block_XY ( ref_frame, list, pres_x, pres_y, COEF[dx==1?0:2], COEF[dy==1?0:2], max_x, max_y, block4 );
}
else
{ // two positions at the horizontal edge
interp_block_X ( ref_frame, list, pres_x, pres_y+(dy==7), COEF[dx==3?0:1], max_x, max_y, block );
interp_block_X ( ref_frame, list, pres_x, pres_y+(dy==7), COEF[dx==3?1:2], max_x, max_y, block2 );
interp_block_XY ( ref_frame, list, pres_x, pres_y, COEF[dx==3?0:1], COEF[dy==1?0:2], max_x, max_y, block3 );
interp_block_XY ( ref_frame, list, pres_x, pres_y, COEF[dx==3?1:2], COEF[dy==1?0:2], max_x, max_y, block4 );
}
}
else
{ // vertical center of one block
if( dx == 1 || dx == 7 )
{ // two positions at the vertical edge
interp_block_Y ( ref_frame, list, pres_x+(dx==7), pres_y, COEF[dy==3?0:2], max_x, max_y, block );
interp_block_XY ( ref_frame, list, pres_x, pres_y, COEF[dx==1?0:2], COEF[dy==3?0:2], max_x, max_y, block2 );
interp_block_Y ( ref_frame, list, pres_x+(dx==7), pres_y, COEF[ 1 ], max_x, max_y, block3 );
interp_block_XY ( ref_frame, list, pres_x, pres_y, COEF[dx==1?0:2], COEF[ 1 ], max_x, max_y, block4 );
}
else
{ // no edge, both horizontal and vertical interpolation neccessary for each position
interp_block_XY ( ref_frame, list, pres_x, pres_y, COEF[dx==3?0:1], COEF[dy==3?0:1], max_x, max_y, block );
interp_block_XY ( ref_frame, list, pres_x, pres_y, COEF[dx==3?1:2], COEF[dy==3?0:1], max_x, max_y, block2 );
interp_block_XY ( ref_frame, list, pres_x, pres_y, COEF[dx==3?0:1], COEF[dy==3?1:2], max_x, max_y, block3 );
interp_block_XY ( ref_frame, list, pres_x, pres_y, COEF[dx==3?1:2], COEF[dy==3?1:2], max_x, max_y, block4 );
}
}
//average the 4 blocks
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[j][i] = ( block[j][i] + block2[j][i] + block3[j][i] + block4[j][i] ) >> 2;
}
}
#endif
/*!
************************************************************************
* \brief
* Interpolation of 1/4 subpixel
************************************************************************
*/
#ifdef EIGHTH_PEL
void get_quarterpel_block(int ref_frame, StorablePicture **list, int x_pos, int y_pos, struct img_par *img, int block[BLOCK_SIZE][BLOCK_SIZE])
#else
void get_block(int ref_frame, StorablePicture **list, int x_pos, int y_pos, struct img_par *img, int block[BLOCK_SIZE][BLOCK_SIZE])
#endif
{
int dx, dy;
int x, y;
int i, j;
int maxold_x,maxold_y;
int result;
int pres_x;
int pres_y;
int tmp_res[4][9];
static const int COEF[6] = { 1, -5, 20, 20, -5, 1 };
if (list[ref_frame] == no_reference_picture && img->framepoc < img->recovery_poc)
{
printf("list[ref_frame] is equal to 'no reference picture' before RAP\n");
/* fill the block with sample value 128 */
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = 128;
return;
}
dx = x_pos&3;
dy = y_pos&3;
x_pos = (x_pos-dx)/4;
y_pos = (y_pos-dy)/4;
maxold_x = dec_picture->size_x-1;
maxold_y = dec_picture->size_y-1;
if (dec_picture->mb_field[img->current_mb_nr])
maxold_y = dec_picture->size_y/2 - 1;
if (dx == 0 && dy == 0)
{ /* fullpel position */
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i))];
}
else
{ /* other positions */
if (dy == 0)
{ /* No vertical interpolation */
for (j = 0; j < BLOCK_SIZE; j++)
{
for (i = 0; i < BLOCK_SIZE; i++)
{
for (result = 0, x = -2; x < 4; x++)
result += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+x))]*COEF[x+2];
block[i][j] = max(0, min(img->max_imgpel_value, (result+16)/32));
}
}
if ((dx&1) == 1)
{
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = (block[i][j] + list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+dx/2))] +1 )/2;
}
}
else if (dx == 0)
{ /* No horizontal interpolation */
for (j = 0; j < BLOCK_SIZE; j++)
{
for (i = 0; i < BLOCK_SIZE; i++)
{
for (result = 0, y = -2; y < 4; y++)
result += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j+y))][max(0,min(maxold_x,x_pos+i))]*COEF[y+2];
block[i][j] = max(0, min(img->max_imgpel_value, (result+16)/32));
}
}
if ((dy&1) == 1)
{
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = (block[i][j] + list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j+dy/2))][max(0,min(maxold_x,x_pos+i))] +1 )/2;
}
}
else if (dx == 2)
{ /* Vertical & horizontal interpolation */
for (j = -2; j < BLOCK_SIZE+3; j++)
{
for (i = 0; i < BLOCK_SIZE; i++)
for (tmp_res[i][j+2] = 0, x = -2; x < 4; x++)
tmp_res[i][j+2] += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+x))]*COEF[x+2];
}
for (j = 0; j < BLOCK_SIZE; j++)
{
for (i = 0; i < BLOCK_SIZE; i++)
{
for (result = 0, y = -2; y < 4; y++)
result += tmp_res[i][j+y+2]*COEF[y+2];
block[i][j] = max(0, min(img->max_imgpel_value, (result+512)/1024));
}
}
if ((dy&1) == 1)
{
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = (block[i][j] + max(0, min(img->max_imgpel_value, (tmp_res[i][j+2+dy/2]+16)/32)) +1 )/2;
}
}
else if (dy == 2)
{ /* Horizontal & vertical interpolation */
for (j = 0; j < BLOCK_SIZE; j++)
{
for (i = -2; i < BLOCK_SIZE+3; i++)
for (tmp_res[j][i+2] = 0, y = -2; y < 4; y++)
tmp_res[j][i+2] += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j+y))][max(0,min(maxold_x,x_pos+i))]*COEF[y+2];
}
for (j = 0; j < BLOCK_SIZE; j++)
{
for (i = 0; i < BLOCK_SIZE; i++)
{
for (result = 0, x = -2; x < 4; x++)
result += tmp_res[j][i+x+2]*COEF[x+2];
block[i][j] = max(0, min(img->max_imgpel_value, (result+512)/1024));
}
}
if ((dx&1) == 1)
{
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = (block[i][j] + max(0, min(img->max_imgpel_value, (tmp_res[j][i+2+dx/2]+16)/32))+1)/2;
}
}
else
{ /* Diagonal interpolation */
for (j = 0; j < BLOCK_SIZE; j++)
{
for (i = 0; i < BLOCK_SIZE; i++)
{
pres_y = dy == 1 ? y_pos+j : y_pos+j+1;
pres_y = max(0,min(maxold_y,pres_y));
for (result = 0, x = -2; x < 4; x++)
result += list[ref_frame]->imgY[pres_y][max(0,min(maxold_x,x_pos+i+x))]*COEF[x+2];
block[i][j] = max(0, min(img->max_imgpel_value, (result+16)/32));
}
}
for (j = 0; j < BLOCK_SIZE; j++)
{
for (i = 0; i < BLOCK_SIZE; i++)
{
pres_x = dx == 1 ? x_pos+i : x_pos+i+1;
pres_x = max(0,min(maxold_x,pres_x));
for (result = 0, y = -2; y < 4; y++)
result += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j+y))][pres_x]*COEF[y+2];
block[i][j] = (block[i][j] + max(0, min(img->max_imgpel_value, (result+16)/32)) +1 ) / 2;
}
}
}
}
}
#ifdef USE_HP_FILTER
void get_quarterpel_block_enhanced_FDIF(int ref_frame, StorablePicture **list, int x_pos, int y_pos, struct img_par *img, int block[BLOCK_SIZE][BLOCK_SIZE])
{
int dx,dy,i,j,maxold_x,maxold_y;
int pos,m,n,sum,offset,shift;
static const int f0[4][4] = {{0,5,5,0},{5,22,22,5},{5,22,22,5},{0,5,5,0}};
static const int f1[6] = {3,-15,111,37,-10,2};
static const int f2[6] = {3,-17,78,78,-17,3};
static const int f3[6] = {2,-10,37,111,-15,3};
static const int offset_pos[16] = {0,64,64,64,64,192,128,64,64,128,128,128,64,-64,128,64};
static const int shift_pos[16] = {0, 7, 7, 7, 7, 7, 8, 7, 7, 8, 8, 8, 7, 7, 8, 7};
if (list[ref_frame] == no_reference_picture && img->framepoc < img->recovery_poc)
{
printf("list[ref_frame] is equal to 'no reference picture' before RAP\n");
/* fill the block with sample value 128 */
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = 128;
return;
}
dx = x_pos&3;
dy = y_pos&3;
x_pos = (x_pos-dx)/4;
y_pos = (y_pos-dy)/4;
maxold_x = dec_picture->size_x-1;
maxold_y = dec_picture->size_y-1;
if (dec_picture->mb_field[img->current_mb_nr])
maxold_y = dec_picture->size_y/2 - 1;
if (dx == 0 && dy == 0)
{ /* fullpel position */
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i))];
}
else
{ /* other positions */
pos = 4*dy+dx;
offset = offset_pos[pos];
shift = shift_pos[pos];
for (i = 0; i < BLOCK_SIZE; i++)
{
for (j = 0; j < BLOCK_SIZE; j++)
{
sum = 0;
if (pos==1)
for (m=0;m<6;m++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i-2+m))]*f1[m];
if (pos==2)
for (m=0;m<6;m++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i-2+m))]*f2[m];
if (pos==3)
for (m=0;m<6;m++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i-2+m))]*f3[m];
if (pos==4)
for (m=0;m<6;m++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i))]*f1[m];
if (pos==5)
for (m=0;m<6;m++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i-2+m))]*f1[m];
if (pos==6)
for (m=0;m<6;m++)
sum += (list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i-2+m))]*f1[m]+
list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i+3-m))]*f1[m]);
if (pos==7)
for (m=0;m<4;m++)
for (n=0;n<4;n++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-1+m))][max(0,min(maxold_x,x_pos+i-1+n))]*f0[m][n];
if (pos==8)
for (m=0;m<6;m++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i))]*f2[m];
if (pos==9)
for (m=0;m<6;m++)
sum += (list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i-2+m))]*f1[m]+
list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i+3-m))]*f3[m]);
if (pos==10)
for (m=0;m<6;m++)
sum += (list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i-2+m))]*f2[m]+
list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i+3-m))]*f2[m]);
if (pos==11)
for (m=0;m<6;m++)
sum += (list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i-2+m))]*f3[m]+
list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i+3-m))]*f1[m]);
if (pos==12)
for (m=0;m<6;m++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i))]*f3[m];
if (pos==13)
for (m=0;m<6;m++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i+3-m))]*f3[m];
if (pos==14)
for (m=0;m<6;m++)
sum += (list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i-2+m))]*f3[m]+
list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i+3-m))]*f3[m]);
if (pos==15)
for (m=0;m<6;m++)
sum += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j-2+m))][max(0,min(maxold_x,x_pos+i-2+m))]*f3[m];
sum = (sum+offset)>>shift;
block[i][j] = max(0, min(img->max_imgpel_value,sum));
} //for j
} //for i
}
}
const int ONE_FOURTH_TAP[3][2] =
{
{20,20},
{-5,-4},
{ 1, 0},
};
void get_quarterpel_block_16(int ref_frame, StorablePicture **list, int x_pos, int y_pos, struct img_par *img, int block[BLOCK_SIZE][BLOCK_SIZE])
{
int x_sub, y_sub, comp_x, comp_y, pos_y1, pos_y2, pos_x1, pos_x2;
int i, j, ii, jj, ci;
int maxold_x,maxold_y;
int sub_pos, comp_sub_pos;
#ifdef INTERNAL_BIT_DEPTH_INCREASE
//int sub_loc[15][2] =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -