📄 analyse.c.svn-base
字号:
*pi_count = 4; } else { *mode++ = I_PRED_4x4_DC_128; *pi_count = 1; }}static void x264_mb_analyse_intra_chroma( x264_t *h, x264_mb_analysis_t *a ){ int i; int i_max; int predict_mode[9]; uint8_t *p_dstc[2], *p_srcc[2]; int i_stride[2]; if( a->i_sad_i8x8chroma < 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_8x8chroma_mode_available( h->mb.i_neighbour, predict_mode, &i_max ); a->i_sad_i8x8chroma = 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_8x8c[i_mode]( p_dstc[0], i_stride[0] ); h->predict_8x8c[i_mode]( p_dstc[1], i_stride[1] ); /* we calculate the cost */ i_sad = h->pixf.mbcmp[PIXEL_8x8]( p_dstc[0], i_stride[0], p_srcc[0], i_stride[0] ) + h->pixf.mbcmp[PIXEL_8x8]( p_dstc[1], i_stride[1], p_srcc[1], i_stride[1] ) + a->i_lambda * bs_size_ue( x264_mb_pred_mode8x8c_fix[i_mode] ); /* if i_score is lower it is better */ if( a->i_sad_i8x8chroma > i_sad ) { a->i_predict8x8chroma = i_mode; a->i_sad_i8x8chroma = i_sad; } } h->mb.i_chroma_pred_mode = a->i_predict8x8chroma;}static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, 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 f8_satd_rd_ratio = 0; int i, idx; int i_max; int predict_mode[9]; int i_satd_thresh; if( h->sh.i_type == SLICE_TYPE_B ) i_satd_thresh = a->i_best_satd * 9/8; else i_satd_thresh = a->i_best_satd * 5/4 + a->i_lambda * 10; /*---------------- 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]; h->predict_16x16[i_mode]( p_dst, i_stride ); i_sad = h->pixf.mbcmp[PIXEL_16x16]( p_dst, i_stride, p_src, i_stride ) + a->i_lambda * bs_size_ue( x264_mb_pred_mode16x16_fix[i_mode] ); if( a->i_sad_i16x16 > i_sad ) { a->i_predict16x16 = i_mode; a->i_sad_i16x16 = i_sad; } } if( a->b_mbrd ) { f8_satd_rd_ratio = ((unsigned)i_cost_inter << 8) / a->i_best_satd + 1; x264_mb_analyse_intra_chroma( h, a ); if( h->mb.b_chroma_me ) a->i_sad_i16x16 += a->i_sad_i8x8chroma; if( a->i_sad_i16x16 < i_satd_thresh ) { h->mb.i_type = I_16x16; h->mb.i_intra16x16_pred_mode = a->i_predict16x16; a->i_sad_i16x16 = x264_rd_cost_mb( h, a->i_lambda2 ); } else a->i_sad_i16x16 = a->i_sad_i16x16 * f8_satd_rd_ratio >> 8; } else { if( h->sh.i_type == SLICE_TYPE_B ) /* cavlc mb type prefix */ a->i_sad_i16x16 += a->i_lambda * i_mb_b_cost_table[I_16x16]; if( a->b_fast_intra && a->i_sad_i16x16 > 2*i_cost_inter ) return; } /* 4x4 prediction selection */ if( flags & X264_ANALYSE_I4x4 ) { a->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_neighbour4[idx], predict_mode, &i_max ); if( (h->mb.i_neighbour4[idx] & (MB_TOPRIGHT|MB_TOP)) == MB_TOP ) /* emulate missing topright samples */ *(uint32_t*) &p_dst_by[4 - i_stride] = p_dst_by[3 - i_stride] * 0x01010101U; for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; i_mode = predict_mode[i]; h->predict_4x4[i_mode]( p_dst_by, i_stride ); i_sad = h->pixf.mbcmp[PIXEL_4x4]( p_dst_by, i_stride, p_src_by, i_stride ) + a->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix(i_mode) ? 1 : 4); if( i_best > i_sad ) { a->i_predict4x4[x][y] = i_mode; i_best = i_sad; } } a->i_sad_i4x4 += i_best; /* we need to encode this block now (for next ones) */ h->predict_4x4[a->i_predict4x4[x][y]]( p_dst_by, i_stride ); x264_mb_encode_i4x4( h, idx, a->i_qp ); h->mb.cache.intra4x4_pred_mode[x264_scan8[idx]] = a->i_predict4x4[x][y]; } a->i_sad_i4x4 += a->i_lambda * 24; /* from JVT (SATD0) */ if( a->b_mbrd ) { if( h->mb.b_chroma_me ) a->i_sad_i4x4 += a->i_sad_i8x8chroma; if( a->i_sad_i4x4 < i_satd_thresh ) { h->mb.i_type = I_4x4; a->i_sad_i4x4 = x264_rd_cost_mb( h, a->i_lambda2 ); } else a->i_sad_i4x4 = a->i_sad_i4x4 * f8_satd_rd_ratio >> 8; } else { if( h->sh.i_type == SLICE_TYPE_B ) a->i_sad_i4x4 += a->i_lambda * i_mb_b_cost_table[I_4x4]; } } /* 8x8 prediction selection */ if( flags & X264_ANALYSE_I8x8 ) { a->i_sad_i8x8 = 0; for( idx = 0; idx < 4; 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, 4*idx ); x = idx&1; y = idx>>1; p_src_by = p_src + 8 * x + 8 * y * i_stride; p_dst_by = p_dst + 8 * x + 8 * y * i_stride; i_best = COST_MAX; predict_4x4_mode_available( h->mb.i_neighbour8[idx], predict_mode, &i_max ); for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; i_mode = predict_mode[i]; h->predict_8x8[i_mode]( p_dst_by, i_stride, h->mb.i_neighbour8[idx] ); /* could use sa8d, but it doesn't seem worth the speed cost (without mmx at least) */ i_sad = h->pixf.mbcmp[PIXEL_8x8]( p_dst_by, i_stride, p_src_by, i_stride ) + a->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix(i_mode) ? 1 : 4); if( i_best > i_sad ) { a->i_predict8x8[x][y] = i_mode; i_best = i_sad; } } a->i_sad_i8x8 += i_best; /* we need to encode this block now (for next ones) */ h->predict_8x8[a->i_predict8x8[x][y]]( p_dst_by, i_stride, h->mb.i_neighbour ); x264_mb_encode_i8x8( h, idx, a->i_qp ); x264_macroblock_cache_intra8x8_pred( h, 2*x, 2*y, a->i_predict8x8[x][y] ); } if( a->b_mbrd ) { if( h->mb.b_chroma_me ) a->i_sad_i8x8 += a->i_sad_i8x8chroma; if( a->i_sad_i8x8 < i_satd_thresh ) { h->mb.i_type = I_8x8; a->i_sad_i8x8 = x264_rd_cost_mb( h, a->i_lambda2 ); } else a->i_sad_i8x8 = a->i_sad_i8x8 * f8_satd_rd_ratio >> 8; } else { // FIXME some bias like in i4x4? if( h->sh.i_type == SLICE_TYPE_B ) a->i_sad_i8x8 += a->i_lambda * i_mb_b_cost_table[I_8x8]; } }}#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]];#define REF_COST(list, ref) \ (a->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l##list##_active - 1, ref ))static void x264_mb_analyse_inter_p16x16( x264_t *h, x264_mb_analysis_t *a ){ x264_me_t m; int i_ref; int mvc[7][2], i_mvc; int i_halfpel_thresh = INT_MAX; int *p_halfpel_thresh = h->i_ref0>1 ? &i_halfpel_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 = REF_COST( 0, i_ref ); i_halfpel_thresh -= i_ref_cost; m.i_ref_cost = i_ref_cost; m.i_ref = i_ref; /* 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_halfpel_thresh ); m.cost += i_ref_cost; i_halfpel_thresh += i_ref_cost; if( m.cost < a->l0.me16x16.cost ) a->l0.me16x16 = m; /* save mv for predicting neighbors */ a->l0.mvc[i_ref][0][0] = h->mb.mvr[0][i_ref][h->mb.i_mb_xy][0] = m.mv[0]; a->l0.mvc[i_ref][0][1] = h->mb.mvr[0][i_ref][h->mb.i_mb_xy][1] = m.mv[1]; } x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, a->l0.me16x16.i_ref ); if( a->b_mbrd ) { a->i_best_satd = a->l0.me16x16.cost; h->mb.i_type = P_L0; h->mb.i_partition = D_16x16; x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 0, a->l0.me16x16.mv[0], a->l0.me16x16.mv[1] ); a->l0.me16x16.cost = x264_rd_cost_mb( h, a->i_lambda2 ); }}static void x264_mb_analyse_inter_p8x8_mixed_ref( x264_t *h, x264_mb_analysis_t *a ){ x264_me_t m; int i_ref; uint8_t **p_fenc = h->mb.pic.p_fenc; int i_halfpel_thresh = INT_MAX; int *p_halfpel_thresh = /*h->i_ref0>1 ? &i_halfpel_thresh : */NULL; int i; int i_maxref = h->i_ref0-1; h->mb.i_partition = D_8x8; /* early termination: if 16x16 chose ref 0, then evalute no refs older * than those used by the neighbors */ if( i_maxref > 0 && a->l0.me16x16.i_ref == 0 && h->mb.i_mb_type_top && h->mb.i_mb_type_left ) { i_maxref = 0; i_maxref = X264_MAX( i_maxref, h->mb.cache.ref[0][ X264_SCAN8_0 - 8 - 1 ] ); i_maxref = X264_MAX( i_maxref, h->mb.cache.ref[0][ X264_SCAN8_0 - 8 + 0 ] ); i_maxref = X264_MAX( i_maxref, h->mb.cache.ref[0][ X264_SCAN8_0 - 8 + 2 ] ); i_maxref = X264_MAX( i_maxref, h->mb.cache.ref[0][ X264_SCAN8_0 - 8 + 4 ] ); i_maxref = X264_MAX( i_maxref, h->mb.cache.ref[0][ X264_SCAN8_0 + 0 - 1 ] ); i_maxref = X264_MAX( i_maxref, h->mb.cache.ref[0][ X264_SCAN8_0 + 2*8 - 1 ] ); } for( i_ref = 0; i_ref <= i_maxref; i_ref++ ) { a->l0.mvc[i_ref][0][0] = h->mb.mvr[0][i_ref][h->mb.i_mb_xy][0]; a->l0.mvc[i_ref][0][1] = h->mb.mvr[0][i_ref][h->mb.i_mb_xy][1]; } for( i = 0; i < 4; i++ ) { x264_me_t *l0m = &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 ); l0m->cost = INT_MAX; for( i_ref = 0; i_ref <= i_maxref; i_ref++ ) { const int i_ref_cost = REF_COST( 0, i_ref ); i_halfpel_thresh -= i_ref_cost; m.i_ref_cost = i_ref_cost; m.i_ref = i_ref; LOAD_HPELS( &m, h->mb.pic.p_fref[0][i_ref], 8*x8, 8*y8 ); x264_macroblock_cache_ref( h, 2*x8, 2*y8, 2, 2, 0, i_ref );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -