📄 analyse.c
字号:
break; default: x264_log( h, X264_LOG_ERROR, "internal error (!8x8 && !4x4)\n" ); break; } } } x264_mb_analyse_intra( h, &analysis, i_cost ); if( h->mb.b_chroma_me && ( analysis.i_sad_i16x16 < i_cost || ( analysis.i_sad_i4x4 < i_cost ))) { x264_mb_analyse_intra_chroma( h, &analysis ); analysis.i_sad_i16x16 += analysis.i_sad_i8x8; analysis.i_sad_i4x4 += analysis.i_sad_i8x8; } i_intra_type = I_16x16; i_intra_cost = analysis.i_sad_i16x16; if( analysis.i_sad_i4x4 < i_intra_cost ) { i_intra_type = I_4x4; i_intra_cost = analysis.i_sad_i4x4; } if( i_intra_cost < i_cost ) { h->mb.i_type = i_intra_type; i_cost = i_intra_cost; } h->stat.frame.i_intra_cost += i_intra_cost; h->stat.frame.i_inter_cost += i_cost; } } else if( h->sh.i_type == SLICE_TYPE_B ) { int b_skip = 0; analysis.b_direct_available = x264_mb_predict_mv_direct16x16( h ); if( analysis.b_direct_available ) { h->mb.i_type = B_SKIP; x264_mb_mc( h ); /* Conditioning the probe on neighboring block types * doesn't seem to help speed or quality. */ b_skip = x264_macroblock_probe_bskip( h ); } if( !b_skip ) { const unsigned int flags = h->param.analyse.inter; int i_partition; int i_cost; x264_mb_analyse_load_costs( h, &analysis ); /* select best inter mode */ /* direct must be first */ if( analysis.b_direct_available ) x264_mb_analyse_inter_direct( h, &analysis ); x264_mb_analyse_inter_b16x16( h, &analysis ); h->mb.i_type = B_L0_L0; i_partition = D_16x16; i_cost = analysis.l0.me16x16.cost; if( analysis.l1.me16x16.cost < i_cost ) { h->mb.i_type = B_L1_L1; i_cost = analysis.l1.me16x16.cost; } if( analysis.i_cost16x16bi < i_cost ) { h->mb.i_type = B_BI_BI; i_cost = analysis.i_cost16x16bi; } if( analysis.i_cost16x16direct < i_cost ) { h->mb.i_type = B_DIRECT; i_cost = analysis.i_cost16x16direct; } if( flags & X264_ANALYSE_BSUB16x16 ) { x264_mb_analyse_inter_b8x8( h, &analysis ); if( analysis.i_cost8x8bi < i_cost ) { h->mb.i_type = B_8x8; i_partition = D_8x8; i_cost = analysis.i_cost8x8bi; if( h->mb.i_sub_partition[0] == h->mb.i_sub_partition[1] || h->mb.i_sub_partition[2] == h->mb.i_sub_partition[3] ) { x264_mb_analyse_inter_b16x8( h, &analysis ); if( analysis.i_cost16x8bi < i_cost ) { i_partition = D_16x8; i_cost = analysis.i_cost16x8bi; h->mb.i_type = analysis.i_mb_type16x8; } } if( h->mb.i_sub_partition[0] == h->mb.i_sub_partition[2] || h->mb.i_sub_partition[1] == h->mb.i_sub_partition[3] ) { x264_mb_analyse_inter_b8x16( h, &analysis ); if( analysis.i_cost8x16bi < i_cost ) { i_partition = D_8x16; i_cost = analysis.i_cost8x16bi; h->mb.i_type = analysis.i_mb_type8x16; } } } } h->mb.i_partition = i_partition; /* refine qpel */ if( i_partition == D_16x16 ) { analysis.l0.me16x16.cost -= analysis.i_lambda * i_mb_b_cost_table[B_L0_L0]; analysis.l1.me16x16.cost -= analysis.i_lambda * i_mb_b_cost_table[B_L1_L1]; if( h->mb.i_type == B_L0_L0 ) { x264_me_refine_qpel( h, &analysis.l0.me16x16 ); i_cost = analysis.l0.me16x16.cost + analysis.i_lambda * i_mb_b_cost_table[B_L0_L0]; } else if( h->mb.i_type == B_L1_L1 ) { x264_me_refine_qpel( h, &analysis.l1.me16x16 ); i_cost = analysis.l1.me16x16.cost + analysis.i_lambda * i_mb_b_cost_table[B_L1_L1]; } else if( h->mb.i_type == B_BI_BI ) { x264_me_refine_qpel( h, &analysis.l0.me16x16 ); x264_me_refine_qpel( h, &analysis.l1.me16x16 ); } } else if( i_partition == D_16x8 ) { for( i=0; i<2; i++ ) { if( analysis.i_mb_partition16x8[i] != D_L1_8x8 ) x264_me_refine_qpel( h, &analysis.l0.me16x8[i] ); if( analysis.i_mb_partition16x8[i] != D_L0_8x8 ) x264_me_refine_qpel( h, &analysis.l1.me16x8[i] ); } } else if( i_partition == D_8x16 ) { for( i=0; i<2; i++ ) { if( analysis.i_mb_partition8x16[i] != D_L1_8x8 ) x264_me_refine_qpel( h, &analysis.l0.me8x16[i] ); if( analysis.i_mb_partition8x16[i] != D_L0_8x8 ) x264_me_refine_qpel( h, &analysis.l1.me8x16[i] ); } } else if( i_partition == D_8x8 ) { for( i=0; i<4; i++ ) { x264_me_t *m; int i_part_cost_old; int i_type_cost; int i_part_type = h->mb.i_sub_partition[i]; int b_bidir = (i_part_type == D_BI_8x8); if( i_part_type == D_DIRECT_8x8 ) continue; if( x264_mb_partition_listX_table[0][i_part_type] ) { m = &analysis.l0.me8x8[i]; i_part_cost_old = m->cost; i_type_cost = analysis.i_lambda * i_sub_mb_b_cost_table[D_L0_8x8]; m->cost -= i_type_cost; x264_me_refine_qpel( h, m ); if( !b_bidir ) analysis.i_cost8x8bi += m->cost + i_type_cost - i_part_cost_old; } if( x264_mb_partition_listX_table[1][i_part_type] ) { m = &analysis.l1.me8x8[i]; i_part_cost_old = m->cost; i_type_cost = analysis.i_lambda * i_sub_mb_b_cost_table[D_L1_8x8]; m->cost -= i_type_cost; x264_me_refine_qpel( h, m ); if( !b_bidir ) analysis.i_cost8x8bi += m->cost + i_type_cost - i_part_cost_old; } /* TODO: update mvp? */ } } /* best intra mode */ x264_mb_analyse_intra( h, &analysis, i_cost ); if( analysis.i_sad_i16x16 < i_cost ) { h->mb.i_type = I_16x16; i_cost = analysis.i_sad_i16x16; } if( analysis.i_sad_i4x4 < i_cost ) { h->mb.i_type = I_4x4; i_cost = analysis.i_sad_i4x4; } } } /*-------------------- Update MB from the analysis ----------------------*/ h->mb.type[h->mb.i_mb_xy] = h->mb.i_type; switch( h->mb.i_type ) { case I_4x4: for( i = 0; i < 16; i++ ) { h->mb.cache.intra4x4_pred_mode[x264_scan8[i]] = analysis.i_predict4x4[block_idx_x[i]][block_idx_y[i]]; } x264_mb_analyse_intra_chroma( h, &analysis ); h->mb.i_chroma_pred_mode = analysis.i_predict8x8; break; case I_16x16: h->mb.i_intra16x16_pred_mode = analysis.i_predict16x16; x264_mb_analyse_intra_chroma( h, &analysis ); h->mb.i_chroma_pred_mode = analysis.i_predict8x8; break; case P_L0: x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, analysis.l0.i_ref ); switch( h->mb.i_partition ) { case D_16x16: x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 0, analysis.l0.me16x16.mv[0], analysis.l0.me16x16.mv[1] ); break; case D_16x8: x264_macroblock_cache_mv ( h, 0, 0, 4, 2, 0, analysis.l0.me16x8[0].mv[0], analysis.l0.me16x8[0].mv[1] ); x264_macroblock_cache_mv ( h, 0, 2, 4, 2, 0, analysis.l0.me16x8[1].mv[0], analysis.l0.me16x8[1].mv[1] ); break; case D_8x16: x264_macroblock_cache_mv ( h, 0, 0, 2, 4, 0, analysis.l0.me8x16[0].mv[0], analysis.l0.me8x16[0].mv[1] ); x264_macroblock_cache_mv ( h, 2, 0, 2, 4, 0, analysis.l0.me8x16[1].mv[0], analysis.l0.me8x16[1].mv[1] ); break; default: x264_log( h, X264_LOG_ERROR, "internal error P_L0 and partition=%d\n", h->mb.i_partition ); break; } break; case P_8x8: x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, analysis.l0.i_ref ); for( i = 0; i < 4; i++ ) { const int x = 2*(i%2); const int y = 2*(i/2); switch( h->mb.i_sub_partition[i] ) { case D_L0_8x8: x264_macroblock_cache_mv( h, x, y, 2, 2, 0, analysis.l0.me8x8[i].mv[0], analysis.l0.me8x8[i].mv[1] ); break; case D_L0_8x4: x264_macroblock_cache_mv( h, x, y+0, 2, 1, 0, analysis.l0.me8x4[i][0].mv[0], analysis.l0.me8x4[i][0].mv[1] ); x264_macroblock_cache_mv( h, x, y+1, 2, 1, 0, analysis.l0.me8x4[i][1].mv[0], analysis.l0.me8x4[i][1].mv[1] ); break; case D_L0_4x8: x264_macroblock_cache_mv( h, x+0, y, 1, 2, 0, analysis.l0.me4x8[i][0].mv[0], analysis.l0.me4x8[i][0].mv[1] ); x264_macroblock_cache_mv( h, x+1, y, 1, 2, 0, analysis.l0.me4x8[i][1].mv[0], analysis.l0.me4x8[i][1].mv[1] ); break; case D_L0_4x4: x264_macroblock_cache_mv( h, x+0, y+0, 1, 1, 0, analysis.l0.me4x4[i][0].mv[0], analysis.l0.me4x4[i][0].mv[1] ); x264_macroblock_cache_mv( h, x+1, y+0, 1, 1, 0, analysis.l0.me4x4[i][1].mv[0], analysis.l0.me4x4[i][1].mv[1] ); x264_macroblock_cache_mv( h, x+0, y+1, 1, 1, 0, analysis.l0.me4x4[i][2].mv[0], analysis.l0.me4x4[i][2].mv[1] ); x264_macroblock_cache_mv( h, x+1, y+1, 1, 1, 0, analysis.l0.me4x4[i][3].mv[0], analysis.l0.me4x4[i][3].mv[1] ); break; default: x264_log( h, X264_LOG_ERROR, "internal error\n" ); break; } } break; case P_SKIP: { int mvp[2]; x264_mb_predict_mv_pskip( h, mvp ); /* */ h->mb.i_partition = D_16x16; x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, 0 ); x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 0, mvp[0], mvp[1] ); break; } case B_SKIP: /* nothing has changed since x264_macroblock_probe_bskip */ break; case B_DIRECT: x264_mb_load_mv_direct8x8( h, 0 ); x264_mb_load_mv_direct8x8( h, 1 ); x264_mb_load_mv_direct8x8( h, 2 ); x264_mb_load_mv_direct8x8( h, 3 ); break; case B_8x8: /* optimize: cache might not need to be rewritten */ for( i = 0; i < 4; i++ ) x264_mb_cache_mv_b8x8( h, &analysis, i, 1 ); break; default: /* the rest of the B types */ switch( h->mb.i_partition ) { case D_16x16: switch( h->mb.i_type ) { case B_L0_L0: x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, analysis.l0.i_ref ); x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 0, analysis.l0.me16x16.mv[0], analysis.l0.me16x16.mv[1] ); x264_macroblock_cache_ref( h, 0, 0, 4, 4, 1, -1 ); x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 1, 0, 0 ); x264_macroblock_cache_mvd( h, 0, 0, 4, 4, 1, 0, 0 ); break; case B_L1_L1: x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, -1 ); x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 0, 0, 0 ); x264_macroblock_cache_mvd( h, 0, 0, 4, 4, 0, 0, 0 ); x264_macroblock_cache_ref( h, 0, 0, 4, 4, 1, analysis.l1.i_ref ); x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 1, analysis.l1.me16x16.mv[0], analysis.l1.me16x16.mv[1] ); break; case B_BI_BI: x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, analysis.l0.i_ref ); x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 0, analysis.l0.me16x16.mv[0], analysis.l0.me16x16.mv[1] ); x264_macroblock_cache_ref( h, 0, 0, 4, 4, 1, analysis.l1.i_ref ); x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 1, analysis.l1.me16x16.mv[0], analysis.l1.me16x16.mv[1] ); break; } break; case D_16x8: x264_mb_cache_mv_b16x8( h, &analysis, 0, 1 ); x264_mb_cache_mv_b16x8( h, &analysis, 1, 1 ); break; case D_8x16: x264_mb_cache_mv_b8x16( h, &analysis, 0, 1 ); x264_mb_cache_mv_b8x16( h, &analysis, 1, 1 ); break; default: x264_log( h, X264_LOG_ERROR, "internal error (invalid MB type)\n" ); break; } }}#include "slicetype_decision.c"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -