📄 edge-detec.c.svn-base
字号:
{ x264_macroblock_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_macroblock_analyse_inter( 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 mvxp, mvyp; int mvx, mvy; /* Get the predicted MV */ x264_macroblock_partition_set( mb, 0, 0, 0, i_ref, 0, 0 ); x264_macroblock_predict_mv( mb, 0, 0, 0, &mvxp, &mvyp ); mvx = mvxp; mvy = mvyp; i_sad = x264_me_p_umhexagons( 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 == mvxp && mvy == mvyp ) { i_sad -= 16 * res->i_lambda; } else { i_sad += res->i_lambda * (bs_size_se(mvx - mvxp) + bs_size_se(mvy - mvyp)); } 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_macroblock_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_macroblock_predict_mv( mb, 0, 0, 0, &mvp[0][0], &mvp[0][1] ); x264_macroblock_predict_mv( mb, 0, 1, 0, &mvp[1][0], &mvp[1][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 = x264_me_p_umhexagons( 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] ) + x264_me_p_umhexagons( 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 += res->i_lambda * ( bs_size_se(res->i_mv_p16x8[0][0] - mvp[0][0] ) + bs_size_se(res->i_mv_p16x8[0][1] - mvp[0][1] ) + bs_size_se(res->i_mv_p16x8[1][0] - mvp[1][0] ) + bs_size_se(res->i_mv_p16x8[1][1] - mvp[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_macroblock_predict_mv( mb, 0, 0, 0, &mvp[0][0], &mvp[0][1] ); x264_macroblock_predict_mv( mb, 0, 1, 0, &mvp[1][0], &mvp[1][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 = x264_me_p_umhexagons( 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] ) + x264_me_p_umhexagons( 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 += res->i_lambda * ( bs_size_se(res->i_mv_p8x16[0][0] - mvp[0][0] ) + bs_size_se(res->i_mv_p8x16[0][1] - mvp[0][1] ) + bs_size_se(res->i_mv_p8x16[1][0] - mvp[1][0] ) + bs_size_se(res->i_mv_p8x16[1][1] - mvp[1][1] ) ); res->i_sad_p8x16 += 2*res->i_lambda * bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, i_ref ); } if( 1 ) { // x264_macroblock_analyse_inter_p8x8( h,mb, res ); }}/***************************************************************************** * x264_macroblock_analyse: *****************************************************************************/void x264_macroblock_analyse( x264_t *h, x264_macroblock_t *mb, int i_slice_type ){ x264_mb_analysis_t analysis; int i; /* qp TODO */ mb->i_qp_delta = 0; /* init analysis */ analysis.i_qp = x264_clip3( h->pps.i_pic_init_qp + h->sh.i_qp_delta + mb->i_qp_delta, 0, 51 ); analysis.i_lambda = i_qp0_cost_table[analysis.i_qp]; x264_macroblock_analyse_edge( h, mb, &analysis ); /*--------------------------- Do the analysis ---------------------------*/ x264_macroblock_analyse_i16x16( h, mb, &analysis ); x264_macroblock_analyse_i4x4 ( h, mb, &analysis ); if( i_slice_type == SLICE_TYPE_P ) { x264_macroblock_analyse_inter( h, mb, &analysis ); } /*-------------------- Chose the macroblock mode ------------------------*/ /* Do the MB decision */ if( i_slice_type == SLICE_TYPE_I ) { mb->i_type = analysis.i_sad_i4x4 < analysis.i_sad_i16x16 ? I_4x4 : I_16x16; } else { int i_satd;#define BEST_TYPE( type, partition, satd ) \ if( satd != -1 && satd < i_satd ) \ { \ i_satd = satd; \ mb->i_type = type; \ mb->i_partition = partition; \ } 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 );#undef BEST_TYPE } if( IS_INTRA( mb->i_type ) ) { x264_macroblock_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_macroblock_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_macroblock_partition_set( mb, 0, 0, 0, analysis.i_ref_p16x8, analysis.i_mv_p16x8[0][0], analysis.i_mv_p16x8[0][1] ); x264_macroblock_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_macroblock_partition_set( mb, 0, 0, 0, analysis.i_ref_p8x16, analysis.i_mv_p8x16[0][0], analysis.i_mv_p8x16[0][1] ); x264_macroblock_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 < mb_sub_partition_count( mb->i_sub_partition[i] ); i_sub++ ) { x264_macroblock_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; default: fprintf( stderr, "internal error\n" ); break; }}/***************************************************************************** * x264_macroblock_encode: *****************************************************************************/void x264_macroblock_encode( x264_t *h, x264_macroblock_t *mb ){ int i; int i_qscale; /* quantification scale */ i_qscale = x264_clip3( h->pps.i_pic_init_qp + h->sh.i_qp_delta + mb->i_qp_delta, 0, 51 ); if( mb->i_type == I_16x16 ) { /* do the right prediction */ h->predict_16x16[mb->i_intra16x16_pred_mode]( mb->context->p_fdec[0], mb->context->i_fdec[0] ); /* encode the 16x16 macroblock */ x264_mb_encode_i16x16( h, mb, i_qscale ); /* fix the pred mode value */ mb->i_intra16x16_pred_mode = x264_mb_pred_mode16x16_fix( mb->i_intra16x16_pred_mode ); } else if( mb->i_type == I_4x4 ) { for( i = 0; i < 16; i++ ) { uint8_t *p_dst_by; /* Do the right prediction */ p_dst_by = mb->context->p_fdec[0] + 4 * block_idx_x[i] + 4 * block_idx_y[i] * mb->context->i_fdec[0]; h->predict_4x4[mb->block[i].i_intra4x4_pred_mode]( p_dst_by, mb->context->i_fdec[0] ); /* encode one 4x4 block */ x264_mb_encode_4x4( h, mb, i, i_qscale ); /* fix the pred mode value */ mb->block[i].i_intra4x4_pred_mode = x264_mb_pred_mode4x4_fix( mb->block[i].i_intra4x4_pred_mode ); } } else /* Inter MB */ { x264_mb_context_t *ctx = mb->context; int16_t dct4x4[16][4][4]; int i8x8, i4x4, idx; int i_decimate_mb = 0; /* Motion compensation */ x264_macroblock_mc( h, mb, 1 ); for( i8x8 = 0; i8x8 < 4; i8x8++ ) { int16_t luma[4][4]; int i_decimate_8x8; /* encode one 4x4 block */ i_decimate_8x8 = 0; for( i4x4 = 0; i4x4 < 4; i4x4++ ) { uint8_t *p_src, *p_dst; idx = i8x8 * 4 + i4x4; p_src = ctx->p_img[0] + 4 * block_idx_x[idx] + 4 * block_idx_y[idx] * ctx->i_img[0]; p_dst = ctx->p_fdec[0] + 4 * block_idx_x[idx] + 4 * block_idx_y[idx] * ctx->i_fdec[0]; /* we calculate diff */ h->pixf.sub4x4( luma, p_src, ctx->i_img[0],p_dst, ctx->i_fdec[0] ); /* calculate dct coeffs */ h->dctf.dct4x4( dct4x4[idx], luma ); quant_4x4( dct4x4[idx], i_qscale, 1 ); scan_zigzag_4x4full( mb->block[idx].luma4x4, dct4x4[idx] ); i_decimate_8x8 += x264_mb_decimate_score( mb->block[idx].luma4x4, 16 ); } /* decimate this 8x8 block */ i_decimate_mb += i_decimate_8x8; if( i_decimate_8x8 < 4 ) { for( i4x4 = 0; i4x4 < 4; i4x4++ ) { int x, y; idx = i8x8 * 4 + i4x4; for( i = 0; i < 16; i++ ) { mb->block[idx].luma4x4[i] = 0; } for( x = 0; x < 4; x++ ) { for( y = 0; y < 4; y++ ) { dct4x4[idx][x][y] = 0; } } } } } if( i_decimate_mb < 6 ) { for( i8x8 = 0; i8x8 < 4; i8x8++ ) { for( i4x4 = 0; i4x4 < 4; i4x4++ ) { for( i = 0; i < 16; i++ ) { mb->block[i8x8 * 4 + i4x4].luma4x4[i] = 0; } } } } else { for( i8x8 = 0; i8x8 < 4; i8x8++ ) { int16_t luma[4][4]; /* TODO we could avoid it if we had decimate this 8x8 block */ /* output samples to fdec */ for( i4x4 = 0; i4x4 < 4; i4x4++ ) { uint8_t *p_dst; idx = i8x8 * 4 + i4x4; dequant_4x4( dct4x4[idx], i_qscale ); h->dctf.idct4x4( luma, dct4x4[idx] ); /* put pixel to fdec */ p_dst = ctx->p_fdec[0] + 4 * block_idx_x[idx] + 4 * block_idx_y[idx] * ctx->i_fdec[0]; h->pixf.add4x4( p_dst, ctx->i_fdec[0], luma ); } } } } /* encode chroma */ i_qscale = i_chroma_qp_table[x264_clip3( i_qscale + h->pps.i_chroma_qp_index_offset, 0, 51 )]; if( IS_INTRA( mb->i_type ) ) { /* do the right prediction */ h->predict_8x8[mb->i_chroma_pred_mode]( mb->context->p_fdec[1], mb->context->i_fdec[1] ); h->predict_8x8[mb->i_chroma_pred_mode]( mb->context->p_fdec[2], mb->context->i_fdec[2] ); } else { /* Motion compensation */ x264_macroblock_mc( h, mb, 0 ); } /* encode the 8x8 blocks */ x264_mb_encode_8x8( h, mb, !IS_INTRA( mb->i_type ), i_qscale ); /* fix the pred mode value */ if( IS_INTRA( mb->i_type ) ) { mb->i_chroma_pred_mode = x264_mb_pred_mode8x8_fix( mb->i_chroma_pred_mode ); } /* Calculate the Luma/Chroma patern and non_zero_count */ if( mb->i_type == I_16x16 ) { mb->i_cbp_luma = 0x00; for( i = 0; i < 16; i++ ) { mb->block[i].i_non_zero_count = array_non_zero_count( mb->block[i].residual_ac, 15 ); if( mb->block[i].i_non_zero_count > 0 ) { mb->i_cbp_luma = 0x0f; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -