📄 frame.c
字号:
pix[-1] = clip_uint8( p0 + i_delta ); /* p0' */
pix[0] = clip_uint8( q0 - i_delta ); /* q0' */
}
pix += i_pix_stride;
}
}
else
{
/* 2px edge length (because we use same bS than the one for luma) */
for( d = 0; d < 2; d++ )
{
const int p0 = pix[-1];
const int p1 = pix[-2];
const int q0 = pix[0];
const int q1 = pix[1];
if( abs( p0 - q0 ) < alpha &&
abs( p1 - p0 ) < beta &&
abs( q1 - q0 ) < beta )
{
pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */
pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */
}
pix += i_pix_stride;
}
}
}
}
static/* inline */ void deblocking_filter_edgeh( x264_t *h, uint8_t *pix, int i_pix_stride, int bS[4], int i_QP )
{
int i, d;
const int i_index_a = x264_clip3( i_QP + h->sh.i_alpha_c0_offset, 0, 51 );
const int alpha = i_alpha_table[i_index_a];
const int beta = i_beta_table[x264_clip3( i_QP + h->sh.i_beta_offset, 0, 51 )];
int i_pix_next = i_pix_stride;
for( i = 0; i < 4; i++ )
{
if( bS[i] == 0 )
{
pix += 4;
continue;
}
if( bS[i] < 4 )
{
const int tc0 = i_tc0_table[i_index_a][bS[i] - 1];
/* 4px edge length */
for( d = 0; d < 4; d++ )
{
const int p0 = pix[-i_pix_next];
const int p1 = pix[-2*i_pix_next];
const int p2 = pix[-3*i_pix_next];
const int q0 = pix[0];
const int q1 = pix[1*i_pix_next];
const int q2 = pix[2*i_pix_next];
if( abs( p0 - q0 ) < alpha &&
abs( p1 - p0 ) < beta &&
abs( q1 - q0 ) < beta )
{
int tc = tc0;
int i_delta;
if( abs( p2 - p0 ) < beta )
{
pix[-2*i_pix_next] = p1 + x264_clip3( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 );
tc++;
}
if( abs( q2 - q0 ) < beta )
{
pix[i_pix_next] = q1 + x264_clip3( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 );
tc++;
}
i_delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
pix[-i_pix_next] = clip_uint8( p0 + i_delta ); /* p0' */
pix[0] = clip_uint8( q0 - i_delta ); /* q0' */
}
pix++;
}
}
else
{
/* 4px edge length */
for( d = 0; d < 4; d++ )
{
const int p0 = pix[-i_pix_next];
const int p1 = pix[-2*i_pix_next];
const int p2 = pix[-3*i_pix_next];
const int q0 = pix[0];
const int q1 = pix[1*i_pix_next];
const int q2 = pix[2*i_pix_next];
if( abs( p0 - q0 ) < alpha &&
abs( p1 - p0 ) < beta &&
abs( q1 - q0 ) < beta )
{
const int p3 = pix[-4*i_pix_next];
const int q3 = pix[ 3*i_pix_next];
if( abs( p0 - q0 ) < (( alpha >> 2 ) + 2 ) )
{
if( abs( p2 - p0 ) < beta )
{
/* p0', p1', p2' */
pix[-1*i_pix_next] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
pix[-2*i_pix_next] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
pix[-3*i_pix_next] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
}
else
{
/* p0' */
pix[-1*i_pix_next] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
}
if( abs( q2 - q0 ) < beta )
{
/* q0', q1', q2' */
pix[0*i_pix_next] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
pix[1*i_pix_next] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
pix[2*i_pix_next] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
}
else
{
/* q0' */
pix[0*i_pix_next] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
}
}
else
{
/* p0' */
pix[-1*i_pix_next] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
/* q0' */
pix[0*i_pix_next] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
}
}
pix++;
}
}
}
}
static/* inline */ void deblocking_filter_edgech( x264_t *h, uint8_t *pix, int i_pix_stride, int bS[4], int i_QP )
{
int i, d;
const int i_index_a = x264_clip3( i_QP + h->sh.i_alpha_c0_offset, 0, 51 );
const int alpha = i_alpha_table[i_index_a];
const int beta = i_beta_table[x264_clip3( i_QP + h->sh.i_beta_offset, 0, 51 )];
int i_pix_next = i_pix_stride;
for( i = 0; i < 4; i++ )
{
if( bS[i] == 0 )
{
pix += 2;
continue;
}
if( bS[i] < 4 )
{
int tc = i_tc0_table[i_index_a][bS[i] - 1] + 1;
/* 2px edge length (see deblocking_filter_edgecv) */
for( d = 0; d < 2; d++ )
{
const int p0 = pix[-1*i_pix_next];
const int p1 = pix[-2*i_pix_next];
const int q0 = pix[0];
const int q1 = pix[1*i_pix_next];
if( abs( p0 - q0 ) < alpha &&
abs( p1 - p0 ) < beta &&
abs( q1 - q0 ) < beta )
{
int i_delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
pix[-i_pix_next] = clip_uint8( p0 + i_delta ); /* p0' */
pix[0] = clip_uint8( q0 - i_delta ); /* q0' */
}
pix++;
}
}
else
{
/* 2px edge length (see deblocking_filter_edgecv) */
for( d = 0; d < 2; d++ )
{
const int p0 = pix[-1*i_pix_next];
const int p1 = pix[-2*i_pix_next];
const int q0 = pix[0];
const int q1 = pix[1*i_pix_next];
if( abs( p0 - q0 ) < alpha &&
abs( p1 - p0 ) < beta &&
abs( q1 - q0 ) < beta )
{
pix[-i_pix_next] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */
pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */
}
pix++;
}
}
}
}
void x264_frame_deblocking_filter( x264_t *h, int i_slice_type )
{
int mb_xy;
for( mb_xy = 0; mb_xy < h->sps->i_mb_width * h->sps->i_mb_height; mb_xy++ )
{
x264_macroblock_t *mb; /* current macroblock */
int i_edge;
int i_dir;
mb = &h->mb[mb_xy];
/* i_dir == 0 -> vertical edge
* i_dir == 1 -> horizontal edge */
for( i_dir = 0; i_dir < 2; i_dir++ )
{
int i_start;
int i_QP;
i_start = (( i_dir == 0 && mb->i_mb_x != 0 ) || ( i_dir == 1 && mb->i_mb_y != 0 ) ) ? 0 : 1;
for( i_edge = i_start; i_edge < 4; i_edge++ )
{
x264_macroblock_t *mbn;
int bS[4]; /* filtering strength */
/* *** neighbour macroblock for the current edge (or current) *** */
mbn = i_edge > 0 ? mb : ( i_dir == 0 ? mb - 1 : mb - h->sps->i_mb_width );
/* *** Get bS for each 4px for the current edge *** */
if( IS_INTRA( mb->i_type ) || IS_INTRA( mbn->i_type ) )
{
bS[0] = bS[1] = bS[2] = bS[3] = ( i_edge == 0 ? 4 : 3 );
}
else
{
int i;
for( i = 0; i < 4; i++ )
{
int x, y;
int xn, yn;
x = i_dir == 0 ? i_edge : i;
y = i_dir == 0 ? i : i_edge;
xn = (x - (i_dir == 0 ? 1 : 0 ))&0x03;
yn = (y - (i_dir == 0 ? 0 : 1 ))&0x03;
if( mb->block[block_idx_xy[x][y]].i_non_zero_count != 0 ||
mbn->block[block_idx_xy[xn][yn]].i_non_zero_count != 0 )
{
bS[i] = 2;
}
else if( i_slice_type == SLICE_TYPE_B )
{
/* FIXME */
fprintf( stderr, "deblocking filter doesn't work yet with B slice\n" );
return;
}
else /* SLICE_TYPE_P */
{
if( mb->partition[x][y].i_ref[0] != mbn->partition[xn][yn].i_ref[0] ||
abs( mb->partition[x][y].mv[0][0] - mbn->partition[xn][yn].mv[0][0] ) >= 4 ||
abs( mb->partition[x][y].mv[0][1] - mbn->partition[xn][yn].mv[0][1] ) >= 4 )
{
bS[i] = 1;
}
else
{
bS[i] = 0;
}
}
}
}
/* *** filter *** */
/* Y plane */
i_QP = ( mb->i_qp + mbn->i_qp + 1 ) >> 1;
if( i_dir == 0 )
{
/* vertical edge */
deblocking_filter_edgev( h, &h->fdec->plane[0][16 * mb->i_mb_y * h->fdec->i_stride[0]+ 16 * mb->i_mb_x + 4 * i_edge],
h->fdec->i_stride[0], bS, i_QP );
if( (i_edge % 2) == 0 )
{
/* U/V planes */
i_QP = ( i_chroma_qp_table[mb->i_qp] + i_chroma_qp_table[mbn->i_qp] + 1 ) >> 1;
deblocking_filter_edgecv( h, &h->fdec->plane[1][8*(mb->i_mb_y*h->fdec->i_stride[1]+mb->i_mb_x)+i_edge*2],
h->fdec->i_stride[1], bS, i_QP );
deblocking_filter_edgecv( h, &h->fdec->plane[2][8*(mb->i_mb_y*h->fdec->i_stride[2]+mb->i_mb_x)+i_edge*2],
h->fdec->i_stride[2], bS, i_QP );
}
}
else
{
/* horizontal edge */
deblocking_filter_edgeh( h, &h->fdec->plane[0][(16*mb->i_mb_y + 4 * i_edge) * h->fdec->i_stride[0]+ 16 * mb->i_mb_x],
h->fdec->i_stride[0], bS, i_QP );
/* U/V planes */
if( ( i_edge % 2 ) == 0 )
{
i_QP = ( i_chroma_qp_table[mb->i_qp] + i_chroma_qp_table[mbn->i_qp] + 1 ) >> 1;
deblocking_filter_edgech( h, &h->fdec->plane[1][8*(mb->i_mb_y*h->fdec->i_stride[1]+mb->i_mb_x)+i_edge*2*h->fdec->i_stride[1]],
h->fdec->i_stride[1], bS, i_QP );
deblocking_filter_edgech( h, &h->fdec->plane[2][8*(mb->i_mb_y*h->fdec->i_stride[2]+mb->i_mb_x)+i_edge*2*h->fdec->i_stride[2]],
h->fdec->i_stride[2], bS, i_QP );
}
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -