📄 analyse.c
字号:
/* top and left available */ *mode++ = I_PRED_CHROMA_V; *mode++ = I_PRED_CHROMA_H; *mode++ = I_PRED_CHROMA_DC; *mode++ = I_PRED_CHROMA_P; *pi_count = 4; } else if( i_neighbour & MB_LEFT ) { /* left available*/ *mode++ = I_PRED_CHROMA_DC_LEFT; *mode++ = I_PRED_CHROMA_H; *pi_count = 2; } else if( i_neighbour & MB_TOP ) { /* top available*/ *mode++ = I_PRED_CHROMA_DC_TOP; *mode++ = I_PRED_CHROMA_V; *pi_count = 2; } else { /* none available */ *mode = I_PRED_CHROMA_DC_128; *pi_count = 1; }}/* MAX = 9 */static void predict_4x4_mode_available( unsigned int i_neighbour, int *mode, int *pi_count ){ int b_l = i_neighbour & MB_LEFT; int b_t = i_neighbour & MB_TOP; if( b_l && b_t ) { *pi_count = 6; *mode++ = I_PRED_4x4_DC; *mode++ = I_PRED_4x4_H; *mode++ = I_PRED_4x4_V; *mode++ = I_PRED_4x4_DDL; if( i_neighbour & MB_TOPLEFT ) { *mode++ = I_PRED_4x4_DDR; *mode++ = I_PRED_4x4_VR; *mode++ = I_PRED_4x4_HD; *pi_count += 3; } *mode++ = I_PRED_4x4_VL; *mode++ = I_PRED_4x4_HU; } else if( b_l ) { *mode++ = I_PRED_4x4_DC_LEFT; *mode++ = I_PRED_4x4_H; *mode++ = I_PRED_4x4_HU; *pi_count = 3; } else if( b_t ) { *mode++ = I_PRED_4x4_DC_TOP; *mode++ = I_PRED_4x4_V; *mode++ = I_PRED_4x4_DDL; *mode++ = I_PRED_4x4_VL; *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[4]; uint8_t *p_dstc[2], *p_srcc[2]; if( a->i_satd_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]; predict_8x8chroma_mode_available( h->mb.i_neighbour, predict_mode, &i_max ); a->i_satd_i8x8chroma = COST_MAX; if( i_max == 4 && h->pixf.intra_satd_x3_8x8c && h->pixf.mbcmp[0] == h->pixf.satd[0] ) { int satdu[4], satdv[4]; h->pixf.intra_satd_x3_8x8c( p_srcc[0], p_dstc[0], satdu ); h->pixf.intra_satd_x3_8x8c( p_srcc[1], p_dstc[1], satdv ); h->predict_8x8c[I_PRED_CHROMA_P]( p_dstc[0] ); h->predict_8x8c[I_PRED_CHROMA_P]( p_dstc[1] ); satdu[I_PRED_CHROMA_P] = h->pixf.mbcmp[PIXEL_8x8]( p_dstc[0], FDEC_STRIDE, p_srcc[0], FENC_STRIDE ); satdv[I_PRED_CHROMA_P] = h->pixf.mbcmp[PIXEL_8x8]( p_dstc[1], FDEC_STRIDE, p_srcc[1], FENC_STRIDE ); for( i=0; i<i_max; i++ ) { int i_mode = predict_mode[i]; int i_satd = satdu[i_mode] + satdv[i_mode] + a->i_lambda * bs_size_ue(i_mode); a->i_satd_i8x8chroma_dir[i] = i_satd; COPY2_IF_LT( a->i_satd_i8x8chroma, i_satd, a->i_predict8x8chroma, i_mode ); } } else { for( i=0; i<i_max; i++ ) { int i_satd; int i_mode = predict_mode[i]; /* we do the prediction */ h->predict_8x8c[i_mode]( p_dstc[0] ); h->predict_8x8c[i_mode]( p_dstc[1] ); /* we calculate the cost */ i_satd = h->pixf.mbcmp[PIXEL_8x8]( p_dstc[0], FDEC_STRIDE, p_srcc[0], FENC_STRIDE ) + h->pixf.mbcmp[PIXEL_8x8]( p_dstc[1], FDEC_STRIDE, p_srcc[1], FENC_STRIDE ) + a->i_lambda * bs_size_ue( x264_mb_pred_mode8x8c_fix[i_mode] ); a->i_satd_i8x8chroma_dir[i] = i_satd; COPY2_IF_LT( a->i_satd_i8x8chroma, i_satd, a->i_predict8x8chroma, i_mode ); } } 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_satd_inter ){ const unsigned int flags = h->sh.i_type == SLICE_TYPE_I ? h->param.analyse.intra : h->param.analyse.inter; 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]; int b_merged_satd = h->pixf.intra_satd_x3_16x16 && h->pixf.mbcmp[0] == h->pixf.satd[0]; /*---------------- Try all mode and calculate their score ---------------*/ /* 16x16 prediction selection */ predict_16x16_mode_available( h->mb.i_neighbour, predict_mode, &i_max ); if( b_merged_satd && i_max == 4 ) { h->pixf.intra_satd_x3_16x16( p_src, p_dst, a->i_satd_i16x16_dir ); h->predict_16x16[I_PRED_16x16_P]( p_dst ); a->i_satd_i16x16_dir[I_PRED_16x16_P] = h->pixf.mbcmp[PIXEL_16x16]( p_dst, FDEC_STRIDE, p_src, FENC_STRIDE ); for( i=0; i<4; i++ ) { int cost = a->i_satd_i16x16_dir[i] += a->i_lambda * bs_size_ue(i); COPY2_IF_LT( a->i_satd_i16x16, cost, a->i_predict16x16, i ); } } else { for( i = 0; i < i_max; i++ ) { int i_satd; int i_mode = predict_mode[i]; h->predict_16x16[i_mode]( p_dst ); i_satd = h->pixf.mbcmp[PIXEL_16x16]( p_dst, FDEC_STRIDE, p_src, FENC_STRIDE ) + a->i_lambda * bs_size_ue( x264_mb_pred_mode16x16_fix[i_mode] ); COPY2_IF_LT( a->i_satd_i16x16, i_satd, a->i_predict16x16, i_mode ); a->i_satd_i16x16_dir[i_mode] = i_satd; } } if( h->sh.i_type == SLICE_TYPE_B ) /* cavlc mb type prefix */ a->i_satd_i16x16 += a->i_lambda * i_mb_b_cost_table[I_16x16]; if( a->b_fast_intra && a->i_satd_i16x16 > 2*i_satd_inter ) return; /* 8x8 prediction selection */ if( flags & X264_ANALYSE_I8x8 ) { DECLARE_ALIGNED( uint8_t, edge[33], 8 ); x264_pixel_cmp_t sa8d = (*h->pixf.mbcmp == *h->pixf.sad) ? h->pixf.sad[PIXEL_8x8] : h->pixf.sa8d[PIXEL_8x8]; int i_satd_thresh = a->b_mbrd ? COST_MAX : X264_MIN( i_satd_inter, a->i_satd_i16x16 ); int i_cost = 0; b_merged_satd = h->pixf.intra_sa8d_x3_8x8 && h->pixf.mbcmp[0] == h->pixf.satd[0]; // FIXME some bias like in i4x4? if( h->sh.i_type == SLICE_TYPE_B ) i_cost += a->i_lambda * i_mb_b_cost_table[I_8x8]; for( idx = 0;; idx++ ) { int x = idx&1; int y = idx>>1; uint8_t *p_src_by = p_src + 8*x + 8*y*FENC_STRIDE; uint8_t *p_dst_by = p_dst + 8*x + 8*y*FDEC_STRIDE; int i_best = COST_MAX; int i_pred_mode = x264_mb_predict_intra4x4_mode( h, 4*idx ); predict_4x4_mode_available( h->mb.i_neighbour8[idx], predict_mode, &i_max ); x264_predict_8x8_filter( p_dst_by, edge, h->mb.i_neighbour8[idx], ALL_NEIGHBORS ); if( b_merged_satd && i_max == 9 ) { int satd[3]; h->pixf.intra_sa8d_x3_8x8( p_src_by, edge, satd ); if( i_pred_mode < 3 ) satd[i_pred_mode] -= 3 * a->i_lambda; for( i=2; i>=0; i-- ) { int cost = a->i_satd_i8x8_dir[i][idx] = satd[i] + 4 * a->i_lambda; COPY2_IF_LT( i_best, cost, a->i_predict8x8[idx], i ); } i = 3; } else i = 0; for( ; i<i_max; i++ ) { int i_satd; int i_mode = predict_mode[i]; h->predict_8x8[i_mode]( p_dst_by, edge ); i_satd = sa8d( p_dst_by, FDEC_STRIDE, p_src_by, FENC_STRIDE ) + a->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix(i_mode) ? 1 : 4); COPY2_IF_LT( i_best, i_satd, a->i_predict8x8[idx], i_mode ); a->i_satd_i8x8_dir[i_mode][idx] = i_satd; } i_cost += i_best; if( idx == 3 || i_cost > i_satd_thresh ) break; /* we need to encode this block now (for next ones) */ h->predict_8x8[a->i_predict8x8[idx]]( p_dst_by, edge ); x264_mb_encode_i8x8( h, idx, a->i_qp ); x264_macroblock_cache_intra8x8_pred( h, 2*x, 2*y, a->i_predict8x8[idx] ); } if( idx == 3 ) a->i_satd_i8x8 = i_cost; else { a->i_satd_i8x8 = COST_MAX; i_cost = i_cost * 4/(idx+1); } if( X264_MIN(i_cost, a->i_satd_i16x16) > i_satd_inter*(5+a->b_mbrd)/4 ) return; } /* 4x4 prediction selection */ if( flags & X264_ANALYSE_I4x4 ) { int i_cost; int i_satd_thresh = X264_MIN3( i_satd_inter, a->i_satd_i16x16, a->i_satd_i8x8 ); b_merged_satd = h->pixf.intra_satd_x3_4x4 && h->pixf.mbcmp[0] == h->pixf.satd[0]; if( a->b_mbrd ) i_satd_thresh = i_satd_thresh * (10-a->b_fast_intra)/8; i_cost = a->i_lambda * 24; /* from JVT (SATD0) */ if( h->sh.i_type == SLICE_TYPE_B ) i_cost += a->i_lambda * i_mb_b_cost_table[I_4x4]; for( idx = 0;; idx++ ) { int x = block_idx_x[idx]; int y = block_idx_y[idx]; uint8_t *p_src_by = p_src + 4*x + 4*y*FENC_STRIDE; uint8_t *p_dst_by = p_dst + 4*x + 4*y*FDEC_STRIDE; int i_best = COST_MAX; int i_pred_mode = x264_mb_predict_intra4x4_mode( h, idx ); 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 - FDEC_STRIDE] = p_dst_by[3 - FDEC_STRIDE] * 0x01010101U; if( b_merged_satd && i_max >= 6 ) { int satd[3]; h->pixf.intra_satd_x3_4x4( p_src_by, p_dst_by, satd ); if( i_pred_mode < 3 ) satd[i_pred_mode] -= 3 * a->i_lambda; for( i=2; i>=0; i-- ) COPY2_IF_LT( i_best, satd[i] + 4 * a->i_lambda, a->i_predict4x4[idx], i ); i = 3; } else i = 0; for( ; i<i_max; i++ ) { int i_satd; int i_mode = predict_mode[i]; h->predict_4x4[i_mode]( p_dst_by ); i_satd = h->pixf.mbcmp[PIXEL_4x4]( p_dst_by, FDEC_STRIDE, p_src_by, FENC_STRIDE ) + a->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix(i_mode) ? 1 : 4); COPY2_IF_LT( i_best, i_satd, a->i_predict4x4[idx], i_mode ); } i_cost += i_best; if( i_cost > i_satd_thresh || idx == 15 ) break; /* we need to encode this block now (for next ones) */ h->predict_4x4[a->i_predict4x4[idx]]( p_dst_by ); x264_mb_encode_i4x4( h, idx, a->i_qp ); h->mb.cache.intra4x4_pred_mode[x264_scan8[idx]] = a->i_predict4x4[idx]; } if( idx == 15 ) a->i_satd_i4x4 = i_cost; else a->i_satd_i4x4 = COST_MAX; }}static void x264_intra_rd( x264_t *h, x264_mb_analysis_t *a, int i_satd_thresh ){ if( a->i_satd_i16x16 <= i_satd_thresh ) { h->mb.i_type = I_16x16; x264_analyse_update_cache( h, a ); a->i_satd_i16x16 = x264_rd_cost_mb( h, a->i_lambda2 ); } else a->i_satd_i16x16 = COST_MAX; if( a->i_satd_i4x4 <= i_satd_thresh && a->i_satd_i4x4 < COST_MAX ) { h->mb.i_type = I_4x4; x264_analyse_update_cache( h, a ); a->i_satd_i4x4 = x264_rd_cost_mb( h, a->i_lambda2 ); } else a->i_satd_i4x4 = COST_MAX; if( a->i_satd_i8x8 <= i_satd_thresh && a->i_satd_i8x8 < COST_MAX ) { h->mb.i_type = I_8x8; x264_analyse_update_cache( h, a ); a->i_satd_i8x8 = x264_rd_cost_mb( h, a->i_lambda2 ); } else a->i_satd_i8x8 = COST_MAX;}static void x264_intra_rd_refine( x264_t *h, x264_mb_analysis_t *a ){ uint8_t *p_src = h->mb.pic.p_fenc[0]; uint8_t *p_dst = h->mb.pic.p_fdec[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -