?? analyse.c
字號:
switch( test8x8_mode[i_test] ) { case D_L0_8x8: i_satd += res->i_lambda * bs_size_ue( 0 ); break; case D_L0_8x4: i_satd += res->i_lambda * bs_size_ue( 1 ); break; case D_L0_4x8: i_satd += res->i_lambda * bs_size_ue( 2 ); break; case D_L0_4x4: i_satd += res->i_lambda * bs_size_ue( 3 ); break; default: fprintf( stderr, "internal error (invalid sub type)\n" ); break; } if( i_b_satd == -1 || i_b_satd > i_satd ) { i_b_satd = i_satd; res->i_sub_partition_p8x8[i] = test8x8_mode[i_test];; for( i_sub = 0; i_sub < x264_mb_partition_count_table[test8x8_mode[i_test]]; i_sub++ ) { res->i_mv_p8x8[i][i_sub][0] = mv[i_sub][0]; res->i_mv_p8x8[i][i_sub][1] = mv[i_sub][1]; } } } res->i_sad_p8x8 += i_b_satd; /* needed for the next block */ mb->i_sub_partition[i] = res->i_sub_partition_p8x8[i]; for( i_sub = 0; i_sub < x264_mb_partition_count_table[res->i_sub_partition_p8x8[i]]; i_sub++ ) { x264_mb_partition_set( mb, 0, i, i_sub, res->i_ref_p8x8, res->i_mv_p8x8[i][i_sub][0], res->i_mv_p8x8[i][i_sub][1] ); } } res->i_sad_p8x8 += 4*res->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, i_ref );}static void x264_mb_analyse_inter_p( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ x264_mb_context_t *ctx = mb->context; int i_ref; /* int res */ res->i_sad_p16x16 = -1; res->i_sad_p16x8 = -1; res->i_sad_p8x16 = -1; res->i_sad_p8x8 = -1; /* 16x16 Search on all ref frame */ mb->i_type = P_L0; /* beurk fix that */ mb->i_partition = D_16x16; for( i_ref = 0; i_ref < h->i_ref0; i_ref++ ) { int i_sad; int mvp[2]; int mvx, mvy; /* Get the predicted MV */ x264_mb_partition_set( mb, 0, 0, 0, i_ref, 0, 0 ); x264_mb_predict_mv( mb, 0, 0, 0, mvp ); mvx = mvp[0]; mvy = mvp[1]; i_sad = h->me( h, ctx->p_fref0[i_ref][0], ctx->i_fref0[i_ref][0], ctx->p_img[0], ctx->i_img[0], PIXEL_16x16, res->i_lambda, &mvx, &mvy ); if( mvx == mvp[0] && mvy == mvp[1] ) { i_sad -= 16 * res->i_lambda; } i_sad += res->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, i_ref ); if( res->i_sad_p16x16 == -1 || i_sad < res->i_sad_p16x16 ) { res->i_sad_p16x16 = i_sad; res->i_ref_p16x16 = i_ref; res->i_mv_p16x16[0] = mvx; res->i_mv_p16x16[1] = mvy; } } /* Now do the rafinement (using the ref found in 16x16 mode) */ i_ref = res->i_ref_p16x16; x264_mb_partition_set( mb, 0, 0, 0, i_ref, 0, 0 ); /* try 16x8 */ /* XXX we test i_predict16x16 to try shape with the same direction than edge * We should do a better algo of course (the one with edge dectection to be used * for intra mode too) * */ if( res->i_predict16x16 != I_PRED_16x16_V ) { int mvp[2][2]; mb->i_partition = D_16x8; res->i_ref_p16x8 = i_ref; x264_mb_predict_mv( mb, 0, 0, 0, mvp[0] ); x264_mb_predict_mv( mb, 0, 1, 0, mvp[1] ); res->i_mv_p16x8[0][0] = mvp[0][0]; res->i_mv_p16x8[0][1] = mvp[0][1]; res->i_mv_p16x8[1][0] = mvp[1][0]; res->i_mv_p16x8[1][1] = mvp[1][1]; res->i_sad_p16x8 = h->me( h, ctx->p_fref0[i_ref][0], ctx->i_fref0[i_ref][0], ctx->p_img[0], ctx->i_img[0], PIXEL_16x8, res->i_lambda, &res->i_mv_p16x8[0][0], &res->i_mv_p16x8[0][1] ) + h->me( h, &ctx->p_fref0[i_ref][0][8*ctx->i_fref0[i_ref][0]], ctx->i_fref0[i_ref][0], &ctx->p_img[0][8*ctx->i_img[0]], ctx->i_img[0], PIXEL_16x8, res->i_lambda, &res->i_mv_p16x8[1][0], &res->i_mv_p16x8[1][1] ); res->i_sad_p16x8 += 2*res->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, i_ref ); } /* try 8x16 */ if( res->i_predict16x16 != I_PRED_16x16_H ) { int mvp[2][2]; mb->i_partition = D_8x16; res->i_ref_p8x16 = i_ref; x264_mb_predict_mv( mb, 0, 0, 0, mvp[0] ); x264_mb_predict_mv( mb, 0, 1, 0, mvp[1] ); res->i_mv_p8x16[0][0] = mvp[0][0]; res->i_mv_p8x16[0][1] = mvp[0][1]; res->i_mv_p8x16[1][0] = mvp[1][0]; res->i_mv_p8x16[1][1] = mvp[1][1]; res->i_sad_p8x16 = h->me( h, ctx->p_fref0[i_ref][0], ctx->i_fref0[i_ref][0], ctx->p_img[0], ctx->i_img[0], PIXEL_8x16, res->i_lambda, &res->i_mv_p8x16[0][0], &res->i_mv_p8x16[0][1] ) + h->me( h, &ctx->p_fref0[i_ref][0][8], ctx->i_fref0[i_ref][0], &ctx->p_img[0][8], ctx->i_img[0], PIXEL_8x16, res->i_lambda, &res->i_mv_p8x16[1][0], &res->i_mv_p8x16[1][1] ); res->i_sad_p8x16 += 2*res->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, i_ref ); } /* a bit heuristique : if 4x4 is prefered, the block is probably not homegenous * for now disabled because too slow for too few bits saved */ if( res->i_sad_i4x4 < res->i_sad_i16x16 ) { x264_mb_analyse_inter_p_p8x8( h,mb, res ); }}static void x264_mb_analyse_inter_b( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ x264_mb_context_t *ctx = mb->context; uint8_t pix1[16*16], pix2[16*16]; int i_ref; /* int i_ref0, i_ref1; */ int mvp[2]; res->i_sad_b16x16_l0 = -1; res->i_sad_b16x16_l1 = -1; res->i_sad_b16x16_bi = -1; /* 16x16 L0 Search on all ref frame */ mb->i_type = B_L0_L0; /* beurk fix that */ mb->i_partition = D_16x16; for( i_ref = 0; i_ref < h->i_ref0; i_ref++ ) { int i_sad; int mvx, mvy; /* Get the predicted MV */ x264_mb_partition_set( mb, 0, 0, 0, i_ref, 0, 0 ); x264_mb_predict_mv( mb, 0, 0, 0, mvp ); mvx = mvp[0]; mvy = mvp[1]; i_sad = h->me( h, ctx->p_fref0[i_ref][0], ctx->i_fref0[i_ref][0], ctx->p_img[0], ctx->i_img[0], PIXEL_16x16, res->i_lambda, &mvx, &mvy ); i_sad += res->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, i_ref ); if( res->i_sad_b16x16_l0 == -1 || i_sad < res->i_sad_b16x16_l0 ) { res->i_sad_b16x16_l0 = i_sad; res->i_ref_b16x16_l0 = i_ref; res->i_mv_b16x16_l0[0] = mvx; res->i_mv_b16x16_l0[1] = mvy; } } /* 16x16 L1 Search on all ref frame */ mb->i_type = B_L1_L1; /* beurk fix that */ mb->i_partition = D_16x16; for( i_ref = 0; i_ref < h->i_ref1; i_ref++ ) { int i_sad; int mvx, mvy; /* Get the predicted MV */ x264_mb_partition_set( mb, 1, 0, 0, i_ref, 0, 0 ); x264_mb_predict_mv( mb, 1, 0, 0, mvp ); mvx = mvp[0]; mvy = mvp[1]; i_sad = h->me( h, ctx->p_fref1[i_ref][0], ctx->i_fref1[i_ref][0], ctx->p_img[0], ctx->i_img[0], PIXEL_16x16, res->i_lambda, &mvx, &mvy ); i_sad += res->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l1_active - 1, i_ref ); if( res->i_sad_b16x16_l1 == -1 || i_sad < res->i_sad_b16x16_l1 ) { res->i_sad_b16x16_l1 = i_sad; res->i_ref_b16x16_l1 = i_ref; res->i_mv_b16x16_l1[0] = mvx; res->i_mv_b16x16_l1[1] = mvy; } } /* calculate i_sad_b16x16_bi */ h->mc[MC_LUMA]( ctx->p_fref0[res->i_ref_b16x16_l0][0], ctx->i_fref0[res->i_ref_b16x16_l0][0], pix1, 16, res->i_mv_b16x16_l0[0], res->i_mv_b16x16_l0[1], 16, 16 ); h->mc[MC_LUMA]( ctx->p_fref1[res->i_ref_b16x16_l1][0], ctx->i_fref1[res->i_ref_b16x16_l1][0], pix2, 16, res->i_mv_b16x16_l1[0], res->i_mv_b16x16_l1[1], 16, 16 ); h->pixf.avg[PIXEL_16x16]( pix1, 16, pix2, 16 ); res->i_sad_b16x16_bi = h->pixf.sad[PIXEL_16x16]( ctx->p_img[0], ctx->i_img[0], pix1, 16 ); x264_mb_partition_set( mb, 0, 0, 0, res->i_ref_b16x16_l0, res->i_mv_b16x16_l0[0], res->i_mv_b16x16_l0[1] ); x264_mb_partition_set( mb, 1, 0, 0, res->i_ref_b16x16_l1, res->i_mv_b16x16_l1[0], res->i_mv_b16x16_l1[1] ); x264_mb_predict_mv( mb, 0, 0, 0, mvp ); res->i_sad_b16x16_bi += res->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, res->i_ref_b16x16_l0 ); x264_mb_predict_mv( mb, 1, 0, 0, mvp ); res->i_sad_b16x16_bi += res->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l1_active - 1, res->i_ref_b16x16_l1 );#if 0 /* Now do the rafinement (using the ref found in 16x16 mode) */ i_ref0 = res->i_ref_b16x16_l0; i_ref1 = res->i_ref_b16x16_l1; x264_mb_partition_set( mb, 0, 0, 0, i_ref0, 0, 0 ); x264_mb_partition_set( mb, 1, 0, 0, i_ref1, 0, 0 ); /* now do 16x8 */#endif}/***************************************************************************** * x264_macroblock_analyse: *****************************************************************************/void x264_macroblock_analyse( x264_t *h, x264_macroblock_t *mb ){ x264_mb_analysis_t analysis; int i; /* qp TODO */ mb->i_qp = x264_clip3( h->pps->i_pic_init_qp + h->sh.i_qp_delta + 0, 0, 51 ); /* init analysis */ analysis.i_qp = mb->i_qp; analysis.i_lambda = i_qp0_cost_table[analysis.i_qp]; /*--------------------------- Do the analysis ---------------------------*/ x264_mb_analyse_intra( h, mb, &analysis ); if( h->sh.i_type == SLICE_TYPE_P ) { x264_mb_analyse_inter_p( h, mb, &analysis ); } else if( h->sh.i_type == SLICE_TYPE_B ) { x264_mb_analyse_inter_b( h, mb, &analysis ); } /*-------------------- Chose the macroblock mode ------------------------*/#define BEST_TYPE( type, partition, satd ) \ if( satd != -1 && satd < i_satd ) \ { \ i_satd = satd; \ mb->i_type = type; \ mb->i_partition = partition; \ } if( h->sh.i_type == SLICE_TYPE_I ) { mb->i_type = analysis.i_sad_i4x4 < analysis.i_sad_i16x16 ? I_4x4 : I_16x16; } else if( h->sh.i_type == SLICE_TYPE_P ) { int i_satd = analysis.i_sad_i4x4; mb->i_type = I_4x4; BEST_TYPE( I_16x16, -1, analysis.i_sad_i16x16 ); BEST_TYPE( P_L0, D_16x16, analysis.i_sad_p16x16 ); BEST_TYPE( P_L0, D_16x8 , analysis.i_sad_p16x8 ); BEST_TYPE( P_L0, D_8x16 , analysis.i_sad_p8x16 ); BEST_TYPE( P_8x8, D_8x8 , analysis.i_sad_p8x8 ); } else /* B */ { int i_satd = analysis.i_sad_i4x4; mb->i_type = I_4x4; BEST_TYPE( I_16x16, -1, analysis.i_sad_i16x16 ); BEST_TYPE( B_L0_L0, D_16x16, analysis.i_sad_b16x16_l0 ); BEST_TYPE( B_L1_L1, D_16x16, analysis.i_sad_b16x16_l1 ); BEST_TYPE( B_BI_BI, D_16x16, analysis.i_sad_b16x16_bi ); }#undef BEST_TYPE if( IS_INTRA( mb->i_type ) ) { x264_mb_analyse_intra_chroma( h, mb, &analysis ); } /*-------------------- Update MB from the analysis ----------------------*/ switch( mb->i_type ) { case I_4x4: for( i = 0; i < 16; i++ ) { mb->block[i].i_intra4x4_pred_mode = analysis.i_predict4x4[block_idx_x[i]][block_idx_y[i]]; } mb->i_chroma_pred_mode = analysis.i_predict8x8; break; case I_16x16: mb->i_intra16x16_pred_mode = analysis.i_predict16x16; mb->i_chroma_pred_mode = analysis.i_predict8x8; break; case P_L0: switch( mb->i_partition ) { case D_16x16: x264_mb_partition_set( mb, 0, 0, 0, analysis.i_ref_p16x16, analysis.i_mv_p16x16[0], analysis.i_mv_p16x16[1] ); break; case D_16x8: x264_mb_partition_set( mb, 0, 0, 0, analysis.i_ref_p16x8, analysis.i_mv_p16x8[0][0], analysis.i_mv_p16x8[0][1] ); x264_mb_partition_set( mb, 0, 1, 0, analysis.i_ref_p16x8, analysis.i_mv_p16x8[1][0], analysis.i_mv_p16x8[1][1] ); break; case D_8x16: x264_mb_partition_set( mb, 0, 0, 0, analysis.i_ref_p8x16, analysis.i_mv_p8x16[0][0], analysis.i_mv_p8x16[0][1] ); x264_mb_partition_set( mb, 0, 1, 0, analysis.i_ref_p8x16, analysis.i_mv_p8x16[1][0], analysis.i_mv_p8x16[1][1] ); break; default: fprintf( stderr, "internal error\n" ); break; } break; case P_8x8: for( i = 0; i < 4; i++ ) { int i_sub; mb->i_sub_partition[i] = analysis.i_sub_partition_p8x8[i]; for( i_sub = 0; i_sub < x264_mb_partition_count_table[mb->i_sub_partition[i]]; i_sub++ ) { x264_mb_partition_set( mb, 0, i, i_sub, analysis.i_ref_p8x8, analysis.i_mv_p8x8[i][i_sub][0], analysis.i_mv_p8x8[i][i_sub][1] ); } } break; case B_L0_L0: switch( mb->i_partition ) { case D_16x16: x264_mb_partition_set( mb, 0, 0, 0, analysis.i_ref_b16x16_l0, analysis.i_mv_b16x16_l0[0], analysis.i_mv_b16x16_l0[1] ); /* l1 not used/avaiable */ x264_mb_partition_set( mb, 1, 0, 0, -1, 0, 0 ); break; default: fprintf( stderr, "internal error\n" ); break; } break; case B_L1_L1: switch( mb->i_partition ) { case D_16x16: /* l0 not used/avaiable */ x264_mb_partition_set( mb, 0, 0, 0, -1, 0, 0 ); x264_mb_partition_set( mb, 1, 0, 0, analysis.i_ref_b16x16_l1, analysis.i_mv_b16x16_l1[0], analysis.i_mv_b16x16_l1[1] ); break; default: fprintf( stderr, "internal error\n" ); break; } break; case B_BI_BI: switch( mb->i_partition ) { case D_16x16: x264_mb_partition_set( mb, 0, 0, 0, analysis.i_ref_b16x16_l0, analysis.i_mv_b16x16_l0[0], analysis.i_mv_b16x16_l0[1] ); x264_mb_partition_set( mb, 1, 0, 0, analysis.i_ref_b16x16_l1, analysis.i_mv_b16x16_l1[0], analysis.i_mv_b16x16_l1[1] ); break; default: fprintf( stderr, "internal error\n" ); break; } break; default: fprintf( stderr, "internal error\n" ); break; }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -