📄 analyse.c
字号:
} else if( b_a && !b_b ) { *mode++ = I_PRED_4x4_DC_LEFT; *mode++ = I_PRED_4x4_H; *mode++ = I_PRED_4x4_HU; *pi_count = 3; } else if( !b_a && b_b ) { *mode++ = I_PRED_4x4_DC_TOP; *mode++ = I_PRED_4x4_V; *pi_count = 2; } else { *mode++ = I_PRED_4x4_DC_128; *pi_count = 1; }}static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *res, int i_cost_inter ){ const unsigned int flags = h->sh.i_type == SLICE_TYPE_I ? h->param.analyse.intra : h->param.analyse.inter; const int i_stride = h->mb.pic.i_stride[0]; uint8_t *p_src = h->mb.pic.p_fenc[0]; uint8_t *p_dst = h->mb.pic.p_fdec[0]; int i, idx; int i_max; int predict_mode[9]; /*---------------- Try all mode and calculate their score ---------------*/ /* 16x16 prediction selection */ predict_16x16_mode_available( h->mb.i_neighbour, predict_mode, &i_max ); for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; i_mode = predict_mode[i]; /* we do the prediction */ h->predict_16x16[i_mode]( p_dst, i_stride ); /* we calculate the diff and get the square sum of the diff */ i_sad = h->pixf.satd[PIXEL_16x16]( p_dst, i_stride, p_src, i_stride ) + res->i_lambda * bs_size_ue( x264_mb_pred_mode16x16_fix[i_mode] ); /* if i_score is lower it is better */ if( res->i_sad_i16x16 > i_sad ) { res->i_predict16x16 = i_mode; res->i_sad_i16x16 = i_sad; } } /* cavlc mb type prefix */ if( h->sh.i_type == SLICE_TYPE_B ) res->i_sad_i16x16 += res->i_lambda * i_mb_b_cost_table[I_16x16]; if( res->b_fast_intra ) { if( res->i_sad_i16x16 > 2*i_cost_inter ) return; } /* 4x4 prediction selection */ if( flags & X264_ANALYSE_I4x4 ) { res->i_sad_i4x4 = 0; for( idx = 0; idx < 16; idx++ ) { uint8_t *p_src_by; uint8_t *p_dst_by; int i_best; int x, y; int i_pred_mode; i_pred_mode= x264_mb_predict_intra4x4_mode( h, idx ); x = block_idx_x[idx]; y = block_idx_y[idx]; p_src_by = p_src + 4 * x + 4 * y * i_stride; p_dst_by = p_dst + 4 * x + 4 * y * i_stride; i_best = COST_MAX; predict_4x4_mode_available( h->mb.i_neighbour, idx, predict_mode, &i_max ); for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; i_mode = predict_mode[i]; /* we do the prediction */ h->predict_4x4[i_mode]( p_dst_by, i_stride ); /* we calculate diff and get the square sum of the diff */ i_sad = h->pixf.satd[PIXEL_4x4]( p_dst_by, i_stride, p_src_by, i_stride ); i_sad += res->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix[i_mode] ? 1 : 4); /* if i_score is lower it is better */ if( i_best > i_sad ) { res->i_predict4x4[x][y] = i_mode; i_best = i_sad; } } res->i_sad_i4x4 += i_best; /* we need to encode this mb now (for next ones) */ h->predict_4x4[res->i_predict4x4[x][y]]( p_dst_by, i_stride ); x264_mb_encode_i4x4( h, idx, res->i_qp ); /* we need to store the 'fixed' version */ h->mb.cache.intra4x4_pred_mode[x264_scan8[idx]] = x264_mb_pred_mode4x4_fix[res->i_predict4x4[x][y]]; } res->i_sad_i4x4 += res->i_lambda * 24; /* from JVT (SATD0) */ if( h->sh.i_type == SLICE_TYPE_B ) res->i_sad_i4x4 += res->i_lambda * i_mb_b_cost_table[I_4x4]; }}static void x264_mb_analyse_intra_chroma( x264_t *h, x264_mb_analysis_t *res ){ int i; int i_max; int predict_mode[9]; uint8_t *p_dstc[2], *p_srcc[2]; int i_stride[2]; if( res->i_sad_i8x8 < COST_MAX ) return; /* 8x8 prediction selection for chroma */ p_dstc[0] = h->mb.pic.p_fdec[1]; p_dstc[1] = h->mb.pic.p_fdec[2]; p_srcc[0] = h->mb.pic.p_fenc[1]; p_srcc[1] = h->mb.pic.p_fenc[2]; i_stride[0] = h->mb.pic.i_stride[1]; i_stride[1] = h->mb.pic.i_stride[2]; predict_8x8_mode_available( h->mb.i_neighbour, predict_mode, &i_max ); res->i_sad_i8x8 = COST_MAX; for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; i_mode = predict_mode[i]; /* we do the prediction */ h->predict_8x8[i_mode]( p_dstc[0], i_stride[0] ); h->predict_8x8[i_mode]( p_dstc[1], i_stride[1] ); /* we calculate the cost */ i_sad = h->pixf.satd[PIXEL_8x8]( p_dstc[0], i_stride[0], p_srcc[0], i_stride[0] ) + h->pixf.satd[PIXEL_8x8]( p_dstc[1], i_stride[1], p_srcc[1], i_stride[1] ) + res->i_lambda * bs_size_ue( x264_mb_pred_mode8x8_fix[i_mode] ); /* if i_score is lower it is better */ if( res->i_sad_i8x8 > i_sad ) { res->i_predict8x8 = i_mode; res->i_sad_i8x8 = i_sad; } }}#define LOAD_FENC( m, src, xoff, yoff) \ (m)->i_stride[0] = h->mb.pic.i_stride[0]; \ (m)->i_stride[1] = h->mb.pic.i_stride[1]; \ (m)->p_fenc[0] = &(src)[0][(xoff)+(yoff)*(m)->i_stride[0]]; \ (m)->p_fenc[1] = &(src)[1][((xoff)>>1)+((yoff)>>1)*(m)->i_stride[1]]; \ (m)->p_fenc[2] = &(src)[2][((xoff)>>1)+((yoff)>>1)*(m)->i_stride[1]];#define LOAD_HPELS(m, src, xoff, yoff) \ (m)->p_fref[0] = &(src)[0][(xoff)+(yoff)*(m)->i_stride[0]]; \ (m)->p_fref[1] = &(src)[1][(xoff)+(yoff)*(m)->i_stride[0]]; \ (m)->p_fref[2] = &(src)[2][(xoff)+(yoff)*(m)->i_stride[0]]; \ (m)->p_fref[3] = &(src)[3][(xoff)+(yoff)*(m)->i_stride[0]]; \ (m)->p_fref[4] = &(src)[4][((xoff)>>1)+((yoff)>>1)*(m)->i_stride[1]]; \ (m)->p_fref[5] = &(src)[5][((xoff)>>1)+((yoff)>>1)*(m)->i_stride[1]];static void x264_mb_analyse_inter_p16x16( x264_t *h, x264_mb_analysis_t *a ){ x264_me_t m; int i_ref; int mvc[4][2], i_mvc; int i_fullpel_thresh = INT_MAX; int *p_fullpel_thresh = h->i_ref0>1 ? &i_fullpel_thresh : NULL; /* 16x16 Search on all ref frame */ m.i_pixel = PIXEL_16x16; m.p_cost_mv = a->p_cost_mv; LOAD_FENC( &m, h->mb.pic.p_fenc, 0, 0 ); a->l0.me16x16.cost = INT_MAX; for( i_ref = 0; i_ref < h->i_ref0; i_ref++ ) { const int i_ref_cost = a->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, i_ref ); i_fullpel_thresh -= i_ref_cost; /* search with ref */ LOAD_HPELS( &m, h->mb.pic.p_fref[0][i_ref], 0, 0 ); x264_mb_predict_mv_16x16( h, 0, i_ref, m.mvp ); x264_mb_predict_mv_ref16x16( h, 0, i_ref, mvc, &i_mvc ); x264_me_search_ref( h, &m, mvc, i_mvc, p_fullpel_thresh ); m.cost += i_ref_cost; i_fullpel_thresh += i_ref_cost; if( m.cost < a->l0.me16x16.cost ) { a->l0.i_ref = i_ref; a->l0.me16x16 = m; } /* save mv for predicting neighbors */ h->mb.mvr[0][i_ref][h->mb.i_mb_xy][0] = m.mv[0]; h->mb.mvr[0][i_ref][h->mb.i_mb_xy][1] = m.mv[1]; } /* subtract ref cost, so we don't have to add it for the other P types */ a->l0.me16x16.cost -= a->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, a->l0.i_ref ); /* Set global ref, needed for all others modes */ x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, a->l0.i_ref );}static void x264_mb_analyse_inter_p8x8( x264_t *h, x264_mb_analysis_t *a ){ uint8_t **p_fref = h->mb.pic.p_fref[0][a->l0.i_ref]; uint8_t **p_fenc = h->mb.pic.p_fenc; int mvc[5][2], i_mvc; int i; /* XXX Needed for x264_mb_predict_mv */ h->mb.i_partition = D_8x8; i_mvc = 1; mvc[0][0] = a->l0.me16x16.mv[0]; mvc[0][1] = a->l0.me16x16.mv[1]; for( i = 0; i < 4; i++ ) { x264_me_t *m = &a->l0.me8x8[i]; const int x8 = i%2; const int y8 = i/2; m->i_pixel = PIXEL_8x8; m->p_cost_mv = a->p_cost_mv; LOAD_FENC( m, p_fenc, 8*x8, 8*y8 ); LOAD_HPELS( m, p_fref, 8*x8, 8*y8 ); x264_mb_predict_mv( h, 0, 4*i, 2, m->mvp ); x264_me_search( h, m, mvc, i_mvc ); x264_macroblock_cache_mv( h, 2*x8, 2*y8, 2, 2, 0, m->mv[0], m->mv[1] ); mvc[i_mvc][0] = m->mv[0]; mvc[i_mvc][1] = m->mv[1]; i_mvc++; /* mb type cost */ m->cost += a->i_lambda * i_sub_mb_p_cost_table[D_L0_8x8]; } a->l0.i_cost8x8 = a->l0.me8x8[0].cost + a->l0.me8x8[1].cost + a->l0.me8x8[2].cost + a->l0.me8x8[3].cost;}static void x264_mb_analyse_inter_p16x8( x264_t *h, x264_mb_analysis_t *a ){ uint8_t **p_fref = h->mb.pic.p_fref[0][a->l0.i_ref]; uint8_t **p_fenc = h->mb.pic.p_fenc; int mvc[2][2]; int i; /* XXX Needed for x264_mb_predict_mv */ h->mb.i_partition = D_16x8; for( i = 0; i < 2; i++ ) { x264_me_t *m = &a->l0.me16x8[i]; m->i_pixel = PIXEL_16x8; m->p_cost_mv = a->p_cost_mv; LOAD_FENC( m, p_fenc, 0, 8*i ); LOAD_HPELS( m, p_fref, 0, 8*i ); mvc[0][0] = a->l0.me8x8[2*i].mv[0]; mvc[0][1] = a->l0.me8x8[2*i].mv[1]; mvc[1][0] = a->l0.me8x8[2*i+1].mv[0]; mvc[1][1] = a->l0.me8x8[2*i+1].mv[1]; x264_mb_predict_mv( h, 0, 8*i, 4, m->mvp ); x264_me_search( h, m, mvc, 2 ); x264_macroblock_cache_mv( h, 0, 2*i, 4, 2, 0, m->mv[0], m->mv[1] ); } a->l0.i_cost16x8 = a->l0.me16x8[0].cost + a->l0.me16x8[1].cost;}static void x264_mb_analyse_inter_p8x16( x264_t *h, x264_mb_analysis_t *a ){ uint8_t **p_fref = h->mb.pic.p_fref[0][a->l0.i_ref]; uint8_t **p_fenc = h->mb.pic.p_fenc; int mvc[2][2]; int i; /* XXX Needed for x264_mb_predict_mv */ h->mb.i_partition = D_8x16; for( i = 0; i < 2; i++ ) { x264_me_t *m = &a->l0.me8x16[i]; m->i_pixel = PIXEL_8x16; m->p_cost_mv = a->p_cost_mv; LOAD_FENC( m, p_fenc, 8*i, 0 ); LOAD_HPELS( m, p_fref, 8*i, 0 ); mvc[0][0] = a->l0.me8x8[i].mv[0]; mvc[0][1] = a->l0.me8x8[i].mv[1]; mvc[1][0] = a->l0.me8x8[i+2].mv[0]; mvc[1][1] = a->l0.me8x8[i+2].mv[1]; x264_mb_predict_mv( h, 0, 4*i, 2, m->mvp ); x264_me_search( h, m, mvc, 2 ); x264_macroblock_cache_mv( h, 2*i, 0, 2, 4, 0, m->mv[0], m->mv[1] ); } a->l0.i_cost8x16 = a->l0.me8x16[0].cost + a->l0.me8x16[1].cost;}static int x264_mb_analyse_inter_p4x4_chroma( x264_t *h, x264_mb_analysis_t *a, uint8_t **p_fref, int i8x8, int pixel ){ uint8_t pix1[8*8], pix2[8*8]; const int i_stride = h->mb.pic.i_stride[1]; const int off = 4*(i8x8&1) + 2*(i8x8&2)*i_stride;#define CHROMA4x4MC( width, height, me, x, y ) \ h->mc.mc_chroma( &p_fref[4][off+x+y*i_stride], i_stride, &pix1[x+y*8], 8, (me).mv[0], (me).mv[1], width, height ); \ h->mc.mc_chroma( &p_fref[5][off+x+y*i_stride], i_stride, &pix2[x+y*8], 8, (me).mv[0], (me).mv[1], width, height ); if( pixel == PIXEL_4x4 ) { CHROMA4x4MC( 2,2, a->l0.me4x4[i8x8][0], 0,0 ); CHROMA4x4MC( 2,2, a->l0.me4x4[i8x8][1], 0,2 ); CHROMA4x4MC( 2,2, a->l0.me4x4[i8x8][2], 2,0 ); CHROMA4x4MC( 2,2, a->l0.me4x4[i8x8][3], 2,2 ); } else if( pixel == PIXEL_8x4 ) { CHROMA4x4MC( 4,2, a->l0.me8x4[i8x8][0], 0,0 ); CHROMA4x4MC( 4,2, a->l0.me8x4[i8x8][1], 0,2 ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -