⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 analyse.c

📁 图象压缩程序
💻 C
📖 第 1 页 / 共 2 页
字号:
            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 + -