?? frame.c
字號:
} } }}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 ){ const int s8x8 = 2 * h->mb.i_mb_stride; const int s4x4 = 4 * h->mb.i_mb_stride; int mb_y, mb_x; for( mb_y = 0, mb_x = 0; mb_y < h->sps->i_mb_height; ) { const int mb_xy = mb_y * h->mb.i_mb_stride + mb_x; const int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x; const int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x; int i_edge; int i_dir; /* 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_qpn; i_start = (( i_dir == 0 && mb_x != 0 ) || ( i_dir == 1 && mb_y != 0 ) ) ? 0 : 1; for( i_edge = i_start; i_edge < 4; i_edge++ ) { int mbn_xy = i_edge > 0 ? mb_xy : ( i_dir == 0 ? mb_xy - 1 : mb_xy - h->mb.i_mb_stride ); int mbn_8x8 = i_edge > 0 ? mb_8x8 : ( i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8 ); int mbn_4x4 = i_edge > 0 ? mb_4x4 : ( i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4 ); int bS[4]; /* filtering strength */
//x264_log(h, X264_LOG_DEBUG, "mb %d dir %d edge %d\n", mb_xy, i_dir, i_edge);
/* *** Get bS for each 4px for the current edge *** */ if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy] ) ) { bS[0] = bS[1] = bS[2] = bS[3] = ( i_edge == 0 ? 4 : 3 ); } else { int i; for( i = 0; i < 4; i++ ) { int x = i_dir == 0 ? i_edge : i; int y = i_dir == 0 ? i : i_edge; int xn = (x - (i_dir == 0 ? 1 : 0 ))&0x03; int yn = (y - (i_dir == 0 ? 0 : 1 ))&0x03; if( h->mb.non_zero_count[mb_xy][block_idx_xy[x][y]] != 0 || h->mb.non_zero_count[mbn_xy][block_idx_xy[xn][yn]] != 0 ) { bS[i] = 2; } else { /* FIXME: A given frame may occupy more than one position in * the reference list. So we should compare the frame numbers, * not the indices in the ref list. * No harm yet, as we don't generate that case.*/ int i8p= mb_8x8+(x/2)+(y/2)*s8x8; int i8q= mbn_8x8+(xn/2)+(yn/2)*s8x8; int i4p= mb_4x4+x+y*s4x4; int i4q= mbn_4x4+xn+yn*s4x4; //int l; #if 1 /* Add compare frame poc */ int ref_p0, ref_p1, ref_q0, ref_q1;
ref_p0 = h->mb.ref[0][i8p] < 0 ? -1 : h->fref0[h->mb.ref[0][i8p]]->i_poc; ref_p1 = h->mb.ref[1][i8p] < 0 ? -1 : h->fref1[h->mb.ref[1][i8p]]->i_poc; ref_q0 = h->mb.ref[0][i8q] < 0 ? -1 : h->fref0[h->mb.ref[0][i8q]]->i_poc; ref_q1 = h->mb.ref[1][i8q] < 0 ? -1 : h->fref1[h->mb.ref[1][i8q]]->i_poc; if( ((ref_p0 == ref_q0) && (ref_p1 == ref_q1))
|| ((ref_p0 == ref_q1) && (ref_p1 == ref_q0)) )
{
bS[i] = 0;
// L0 and L1 reference pictures of p0 are different; q0 as well
if (ref_p0 != ref_p1)
{
// compare MV for the same reference picture
if (ref_p0 == ref_q0)
{ bS[i] = (abs( h->mb.mv[0][i4p][0] - h->mb.mv[0][i4q][0] ) >= 4 )| (abs( h->mb.mv[0][i4p][1] - h->mb.mv[0][i4q][1] ) >= 4) | (abs( h->mb.mv[1][i4p][0] - h->mb.mv[1][i4q][0] ) >= 4 )| (abs( h->mb.mv[1][i4p][1] - h->mb.mv[1][i4q][1] ) >= 4); } else { bS[i] = (abs( h->mb.mv[0][i4p][0] - h->mb.mv[1][i4q][0] ) >= 4) | (abs( h->mb.mv[0][i4p][1] - h->mb.mv[1][i4q][1] ) >= 4) | (abs( h->mb.mv[1][i4p][0] - h->mb.mv[0][i4q][0] ) >= 4) | (abs( h->mb.mv[1][i4p][1] - h->mb.mv[0][i4q][1] ) >= 4); } } else { bS[i] = ((abs( h->mb.mv[0][i4p][0] - h->mb.mv[0][i4q][0] ) >= 4) | (abs( h->mb.mv[0][i4p][1] - h->mb.mv[0][i4q][1] ) >= 4) | (abs( h->mb.mv[1][i4p][0] - h->mb.mv[1][i4q][0] ) >= 4) | (abs( h->mb.mv[1][i4p][1] - h->mb.mv[1][i4q][1] ) >= 4)) && ((abs( h->mb.mv[0][i4p][0] - h->mb.mv[1][i4q][0] ) >= 4) | (abs( h->mb.mv[0][i4p][1] - h->mb.mv[1][i4q][1] ) >= 4) | (abs( h->mb.mv[1][i4p][0] - h->mb.mv[0][i4q][0] ) >= 4) | (abs( h->mb.mv[1][i4p][1] - h->mb.mv[0][i4q][1] ) >= 4)); } } else { bS[i] = 1; } #else bS[i] = 0; for( l = 0; l < 1 + (i_slice_type == SLICE_TYPE_B); l++ ) {
//x264_log(h, X264_LOG_DEBUG, "list %d p %d %d q %d %d\n",
// l, i8p, h->mb.ref[l][i8p], i8q,h->mb.ref[l][i8q]); if( h->mb.ref[l][i8p] != h->mb.ref[l][i8q] || abs( h->mb.mv[l][i4p][0] - h->mb.mv[l][i4q][0] ) >= 4 || abs( h->mb.mv[l][i4p][1] - h->mb.mv[l][i4q][1] ) >= 4 ) { bS[i] = 1; break; } } #endif } } }
#if 1
x264_log(h, X264_LOG_DEBUG, "mb %d dir %d edge %d\n", mb_xy, i_dir, i_edge);
{
int i;
for( i = 0; i < 4; i++ )
x264_log(h, X264_LOG_DEBUG, "%d ", bS[i]);
x264_log(h, X264_LOG_DEBUG, "\n");
} #endif /* *** filter *** */ /* Y plane */ i_qp = h->mb.qp[mb_xy]; i_qpn= h->mb.qp[mbn_xy]; if( i_dir == 0 ) { /* vertical edge */ deblocking_filter_edgev( h, &h->fdec->plane[0][16 * mb_y * h->fdec->i_stride[0]+ 16 * mb_x + 4 * i_edge], h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1); if( (i_edge % 2) == 0 ) { /* U/V planes */ int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] + i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1; deblocking_filter_edgecv( h, &h->fdec->plane[1][8*(mb_y*h->fdec->i_stride[1]+mb_x)+i_edge*2], h->fdec->i_stride[1], bS, i_qpc ); deblocking_filter_edgecv( h, &h->fdec->plane[2][8*(mb_y*h->fdec->i_stride[2]+mb_x)+i_edge*2], h->fdec->i_stride[2], bS, i_qpc ); } } else { /* horizontal edge */ deblocking_filter_edgeh( h, &h->fdec->plane[0][(16*mb_y + 4 * i_edge) * h->fdec->i_stride[0]+ 16 * mb_x], h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1 ); /* U/V planes */ if( ( i_edge % 2 ) == 0 ) { int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] + i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1; deblocking_filter_edgech( h, &h->fdec->plane[1][8*(mb_y*h->fdec->i_stride[1]+mb_x)+i_edge*2*h->fdec->i_stride[1]], h->fdec->i_stride[1], bS, i_qpc ); deblocking_filter_edgech( h, &h->fdec->plane[2][8*(mb_y*h->fdec->i_stride[2]+mb_x)+i_edge*2*h->fdec->i_stride[2]], h->fdec->i_stride[2], bS, i_qpc ); } } } } #if 0 { int x, y;
const int i_stride = h->fdec->i_stride[0];
uint8_t *p_tmp = &h->fdec->plane[0][16 * mb_y * i_stride+ 16 * mb_x];
x264_log(h, X264_LOG_DEBUG, "mb %d\n", mb_y*h->sps->i_mb_width + mb_x);
for( y = 0; y < 16; y++ )
{
for( x = 0; x < 16; x++ )
{
x264_log(h, X264_LOG_DEBUG, "%3d ", p_tmp[x]);
}
p_tmp += i_stride;
x264_log(h, X264_LOG_DEBUG, "\n");
}
x264_log(h, X264_LOG_DEBUG, "\n"); } #endif /* next mb */ mb_x++; if( mb_x >= h->sps->i_mb_width ) { mb_x = 0; mb_y++; } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -