📄 edge-detec.c.svn-base
字号:
static int x264_mb_pred_mode8x8_fix( int i_mode ){ if( i_mode == I_PRED_CHROMA_DC_LEFT || i_mode == I_PRED_CHROMA_DC_TOP || i_mode == I_PRED_CHROMA_DC_128 ) { return I_PRED_CHROMA_DC; } return i_mode;}typedef struct{ /* conduct the analysis using this lamda and QP */ int i_lambda; int i_qp; /* Edge histogramme (only luma) */ int i_edge_4x4[4][4][9]; /* mode 2 isn't calculated (DC) */ int i_edge_16x16[4]; /* mode 2 isn't calculated (DC) */ /* I: Intra part */ /* Luma part 16x16 and 4x4 modes stats */ int i_sad_i16x16; int i_predict16x16; int i_sad_i4x4; int i_predict4x4[4][4]; /* Chroma part */ int i_sad_i8x8; int i_predict8x8; /* II: Inter part */ int i_sad_p16x16; int i_ref_p16x16; int i_mv_p16x16[2]; int i_sad_p16x8; int i_ref_p16x8; int i_mv_p16x8[2][2]; int i_sad_p8x16; int i_ref_p8x16; int i_mv_p8x16[2][2]; int i_sad_p8x8; int i_ref_p8x8; int i_sub_partition_p8x8[4]; int i_mv_p8x8[4][4][2];} x264_mb_analysis_t;static const int i_qp0_cost_table[52] ={ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 8, 9,10,11,13,14, 16,18,20,23,25,29,32,36, 40,45,51,57,64,72,81,91};static void x264_macroblock_analyse_edge( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ uint8_t *p_img = mb->context->p_img[0];; int i_img = mb->context->i_img[0]; int dx, dy; int x, y; int i;#define FIX8( f ) ( (int)((f) * 256)) /* init stats (16x16) */ for( i = 0; i < 4; i++ ) { res->i_edge_16x16[i] = 0; } for( y = 0; y < 4; y++ ) { for( x = 0; x < 4; x++ ) { /* init stats (4x4) */ for( i = 0; i < 9; i++ ) { res->i_edge_4x4[y][x][i] = 0; } /* FIXME real interval 0-4 except for border mb */ for( dy = (y==0 ? 1:0); dy < (y==3?3:4); dy++ ) { for( dx = (x==0?1:0); dx < (x==3?3:4); dx++ ) { uint8_t *pix = &p_img[(y*4+dy)*i_img+(x+dx)]; int dgx, dgy; int Ryx; int Ag; int Dg; dgx = (pix[-1*i_img-1]+2*pix[-1*i_img+0]+pix[-1*i_img+1]) - (pix[ 1*i_img-1]+2*pix[ 1*i_img+0]+pix[ 1*i_img+1]); dgy = (pix[-1*i_img+1]+2*pix[ 0*i_img+1]+pix[ 1*i_img+1]) - (pix[-1*i_img-1]+2*pix[ 0*i_img-1]+pix[ 1*i_img-1]); /* XXX angle to test/verify */ Ag = abs( dgx ) + abs( dgy ); if( dgx == 0 ) { Ryx = (4*256)<<8; } else { Ryx = ( dgy << 8 )/ dgx; } if( abs(Ryx) >= FIX8(5.027339) ) { Dg = I_PRED_4x4_V; } else if( abs(Ryx) <= FIX8(0.198912) ) { Dg = I_PRED_4x4_H; } else if( Ryx > FIX8(0.198912) && Ryx <= FIX8(0.668179) ) { Dg = I_PRED_4x4_HD; } else if( Ryx > FIX8(0.668179) && Ryx <= FIX8(1.496606) ) { Dg = I_PRED_4x4_DDR; } else if( Ryx > FIX8(1.496606) && Ryx <= FIX8(5.027339) ) { Dg = I_PRED_4x4_VR; } else if( Ryx > FIX8(-5.027339) && Ryx <= FIX8(-1.496606) ) { Dg = I_PRED_4x4_VL; } else if( Ryx > FIX8(-1.496606) && Ryx <= FIX8(-0.668179) ) { Dg = I_PRED_4x4_DDL; } else if( Ryx > FIX8(-0.668179) && Ryx <= FIX8(-0.198912) ) { Dg = I_PRED_4x4_HU; } else { /* Should never occur */ fprintf( stderr, "mmh bad edge dectection function\n" ); Dg = I_PRED_4x4_DC; } res->i_edge_4x4[y][x][Dg] += Ag; if( abs(Ryx) > FIX8(2.414214) ) { Dg = I_PRED_16x16_V; } else if( abs(Ryx) < FIX8(0.414214) ) { Dg = I_PRED_16x16_H; } else { Dg = I_PRED_16x16_P; } res->i_edge_16x16[Dg] += Ag; } } } }#undef FIX8}static void x264_macroblock_analyse_i16x16( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ uint8_t *p_dst = mb->context->p_fdec[0]; uint8_t *p_src = mb->context->p_img[0]; int i_dst = mb->context->i_fdec[0]; int i_src = mb->context->i_img[0]; int i; int i_max; int predict_mode[4]; res->i_sad_i16x16 = -1; /* 16x16 prediction selection */ predict_16x16_mode_available( mb, predict_mode, &i_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_16x16[i_mode]( p_dst, i_dst ); /* we calculate the diff and get the square sum of the diff */ i_sad = h->pixf.satd[PIXEL_16x16]( p_dst, i_dst, p_src, i_src ) + res->i_lambda * bs_size_ue( x264_mb_pred_mode16x16_fix(i_mode) ); /* if i_score is lower it is better */ if( res->i_sad_i16x16 == -1 || res->i_sad_i16x16 > i_sad ) { res->i_predict16x16 = i_mode; res->i_sad_i16x16 = i_sad; } }}static void x264_macroblock_analyse_i4x4( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ int i, idx; int i_max; int predict_mode[9]; uint8_t *p_dst = mb->context->p_fdec[0]; uint8_t *p_src = mb->context->p_img[0]; int i_dst = mb->context->i_fdec[0]; int i_src = mb->context->i_img[0]; res->i_sad_i4x4 = 0; /* 4x4 prediction selection */ 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; int i_th; i_pred_mode= predict_pred_intra4x4_mode( h, mb, idx ); x = block_idx_x[idx]; y = block_idx_y[idx]; i_th = res->i_edge_4x4[y][x][0]; if( i_th < res->i_edge_4x4[y][x][1] ) i_th = res->i_edge_4x4[y][x][1]; if( i_th < res->i_edge_4x4[y][x][3] ) i_th = res->i_edge_4x4[y][x][3]; if( i_th < res->i_edge_4x4[y][x][4] ) i_th = res->i_edge_4x4[y][x][4]; if( i_th < res->i_edge_4x4[y][x][5] ) i_th = res->i_edge_4x4[y][x][5]; if( i_th < res->i_edge_4x4[y][x][6] ) i_th = res->i_edge_4x4[y][x][6]; if( i_th < res->i_edge_4x4[y][x][7] ) i_th = res->i_edge_4x4[y][x][7]; if( i_th < res->i_edge_4x4[y][x][8] ) i_th = res->i_edge_4x4[y][x][8]; i_th /= 2; res->i_edge_4x4[y][x][2] = i_th; p_src_by = p_src + 4 * x + 4 * y * i_src; p_dst_by = p_dst + 4 * x + 4 * y * i_dst; i_best = -1; predict_4x4_mode_available( mb, idx, predict_mode, &i_max ); for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; int i_fmode; i_mode = predict_mode[i]; i_fmode = x264_mb_pred_mode4x4_fix( i_mode ); if( res->i_edge_4x4[y][x][i_fmode] < i_th ) { continue; } /* we do the prediction */ h->predict_4x4[i_mode]( p_dst_by, i_dst ); /* we calculate diff and get the square sum of the diff */ i_sad = h->pixf.satd[PIXEL_4x4]( p_dst_by, i_dst, p_src_by, i_src ); i_sad += res->i_lambda * (i_pred_mode == i_fmode ? 1 : 4); /* if i_score is lower it is better */ if( i_best == -1 || i_best > i_sad ) { res->i_predict4x4[x][y] = i_mode; i_best = i_sad; } } res->i_sad_i4x4 += i_best; /* we need to encode this mb now (for next ones) */ mb->block[idx].i_intra4x4_pred_mode = res->i_predict4x4[x][y]; h->predict_4x4[res->i_predict4x4[x][y]]( p_dst_by, i_dst ); x264_mb_encode_4x4( h, mb, idx, res->i_qp ); } res->i_sad_i4x4 += res->i_lambda * 24; /* from JVT (SATD0) */}static void x264_macroblock_analyse_intra_chroma( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ int i; int i_max; int predict_mode[9]; uint8_t *p_dstc[2], *p_srcc[2]; int i_dstc[2], i_srcc[2]; /* 8x8 prediction selection for chroma */ p_dstc[0] = mb->context->p_fdec[1]; i_dstc[0] = mb->context->i_fdec[1]; p_dstc[1] = mb->context->p_fdec[2]; i_dstc[1] = mb->context->i_fdec[2]; p_srcc[0] = mb->context->p_img[1]; i_srcc[0] = mb->context->i_img[1]; p_srcc[1] = mb->context->p_img[2]; i_srcc[1] = mb->context->i_img[2]; predict_8x8_mode_available( mb, predict_mode, &i_max ); res->i_sad_i8x8 = -1; for( i = 0; i < i_max; i++ ) { int i_sad; int i_mode; i_mode = predict_mode[i]; /* we do the prediction */ h->predict_8x8[i_mode]( p_dstc[0], i_dstc[0] ); h->predict_8x8[i_mode]( p_dstc[1], i_dstc[1] ); /* we calculate the cost */ i_sad = h->pixf.satd[PIXEL_8x8]( p_dstc[0], i_dstc[0], p_srcc[0], i_srcc[0] ) + h->pixf.satd[PIXEL_8x8]( p_dstc[1], i_dstc[1], p_srcc[1], i_srcc[1] ) + res->i_lambda * bs_size_ue( x264_mb_pred_mode8x8_fix(i_mode) ); /* if i_score is lower it is better */ if( res->i_sad_i8x8 == -1 || res->i_sad_i8x8 > i_sad ) { res->i_predict8x8 = i_mode; res->i_sad_i8x8 = i_sad; } }}static void x264_macroblock_analyse_inter_p8x8( x264_t *h, x264_macroblock_t *mb, x264_mb_analysis_t *res ){ x264_mb_context_t *ctx = mb->context; int i_ref = res->i_ref_p16x16; uint8_t *p_fref = ctx->p_fref0[i_ref][0]; int i_fref = ctx->i_fref0[i_ref][0]; uint8_t *p_img = ctx->p_img[0]; int i_img = ctx->i_img[0]; int i; res->i_ref_p8x8 = i_ref; res->i_sad_p8x8 = 0; mb->i_partition = D_8x8; for( i = 0; i < 4; i++ ) { static const int test8x8_mode[4] = { D_L0_8x8, D_L0_8x4, D_L0_4x8, D_L0_4x4 }; static const int test8x8_pix[4] = { PIXEL_8x8, PIXEL_8x4, PIXEL_4x8, PIXEL_4x4 }; static const int test8x8_pos_x[4][4] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 4, 0, 0 }, { 0, 4, 0, 4 } }; static const int test8x8_pos_y[4][4] = { { 0, 0, 0, 0 }, { 0, 4, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 4, 4 } }; int i_test; int mvp[4][2]; int mv[4][2]; int x, y; int i_sub; int i_b_satd; y = 8 * (i / 2); x = 8 * (i % 2); i_b_satd = -1; i_test = 0; /* FIXME as it's tooooooo slow test only 8x8 */ //for( i_test = 0; i_test < 4; i_test++ ) { int i_satd; i_satd = 0; mb->i_sub_partition[i] = test8x8_mode[i_test]; for( i_sub = 0; i_sub < mb_sub_partition_count( test8x8_mode[i_test] ); i_sub++ ) { x264_macroblock_predict_mv( mb, 0, i, i_sub, &mvp[i_sub][0], &mvp[i_sub][1] ); mv[i_sub][0] = mvp[i_sub][0]; mv[i_sub][1] = mvp[i_sub][1]; i_satd += x264_me_p_umhexagons( h, &p_fref[(y+test8x8_pos_y[i_test][i_sub])*i_fref +x+test8x8_pos_x[i_test][i_sub]], i_fref, &p_img[(y+test8x8_pos_y[i_test][i_sub])*i_img +x+test8x8_pos_x[i_test][i_sub]], i_img, test8x8_pix[i_test], res->i_lambda, &mv[i_sub][0], &mv[i_sub][1] ); i_satd += res->i_lambda * ( bs_size_se( mv[i_sub][0] - mvp[i_sub][0] ) + bs_size_se( mv[i_sub][1] - mvp[i_sub][1] ) ); } 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 < mb_sub_partition_count( 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 < mb_sub_partition_count( res->i_sub_partition_p8x8[i] ); i_sub++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -