encodeframe.c 39.2 KB
Newer Older
{
    INT64 act;
    INT64 a;
    INT64 b;

    // Read activity from the map
    act = (INT64)(*(x->mb_activity_ptr));

    // Calculate a zbin adjustment for this mb
    a = act + 4*cpi->activity_avg;
    b = 4*act + cpi->activity_avg;
    if ( b > a )
        //x->act_zbin_adj = (char)((b * 8) / a) - 8;
        x->act_zbin_adj = 8;
    else
        x->act_zbin_adj = 0;

    // Tmp force to 0 to disable.
    x->act_zbin_adj = 0;

}

John Koleszar's avatar
John Koleszar committed
int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
{
    int Error4x4, Error16x16;
John Koleszar's avatar
John Koleszar committed
    int rate4x4, rate16x16, rateuv;
    int dist4x4, dist16x16, distuv;
    int rate = 0;
    int rate4x4_tokenonly = 0;
    int rate16x16_tokenonly = 0;
    int rateuv_tokenonly = 0;

    x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
    if (cpi->sf.RD && cpi->compressor_speed != 2)
John Koleszar's avatar
John Koleszar committed
    {
        vp8_rd_pick_intra_mbuv_mode(cpi, x, &rateuv, &rateuv_tokenonly, &distuv);
John Koleszar's avatar
John Koleszar committed
        rate += rateuv;

        Error16x16 = vp8_rd_pick_intra16x16mby_mode(cpi, x, &rate16x16, &rate16x16_tokenonly, &dist16x16);
        Error4x4 = vp8_rd_pick_intra4x4mby_modes(cpi, x, &rate4x4, &rate4x4_tokenonly, &dist4x4, Error16x16);
        rate += (Error4x4 < Error16x16) ? rate4x4 : rate16x16;

        if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
        {
            adjust_act_zbin( cpi, rate, x );
            vp8_update_zbin_extra(cpi, x);
        }
        int rate2, best_distortion;
John Koleszar's avatar
John Koleszar committed
        MB_PREDICTION_MODE mode, best_mode = DC_PRED;
        int this_rd;
        Error16x16 = INT_MAX;

John Koleszar's avatar
John Koleszar committed
        for (mode = DC_PRED; mode <= TM_PRED; mode ++)
        {
            x->e_mbd.mode_info_context->mbmi.mode = mode;
            RECON_INVOKE(&cpi->common.rtcd.recon, build_intra_predictors_mby)
                (&x->e_mbd);
            distortion2 = VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16prederror)(x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16);
John Koleszar's avatar
John Koleszar committed
            rate2  = x->mbmode_cost[x->e_mbd.frame_type][mode];
Yunqing Wang's avatar
Yunqing Wang committed
            this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
John Koleszar's avatar
John Koleszar committed

            if (Error16x16 > this_rd)
            {
                Error16x16 = this_rd;
                best_mode = mode;
                best_distortion = distortion2;
        x->e_mbd.mode_info_context->mbmi.mode = best_mode;
        Error4x4 = vp8_pick_intra4x4mby_modes(IF_RTCD(&cpi->rtcd), x, &rate2, &best_distortion);
    if (Error4x4 < Error16x16)
    {
        x->e_mbd.mode_info_context->mbmi.mode = B_PRED;
        vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
John Koleszar's avatar
John Koleszar committed
    }
    else
    {
        vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
    }

    vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
    sum_intra_stats(cpi, x);
    vp8_tokenize_mb(cpi, &x->e_mbd, t);
John Koleszar's avatar
John Koleszar committed

    return rate;
}
#ifdef SPEEDSTATS
extern int cnt_pm;
#endif

extern void vp8_fix_contexts(MACROBLOCKD *x);
John Koleszar's avatar
John Koleszar committed

int vp8cx_encode_inter_macroblock
(
    VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
    int recon_yoffset, int recon_uvoffset
)
{
    MACROBLOCKD *const xd = &x->e_mbd;
    int intra_error = 0;
    int rate;
    int distortion;

    x->skip = 0;

    if (xd->segmentation_enabled)
        x->encode_breakout = cpi->segment_encode_breakout[xd->mode_info_context->mbmi.segment_id];
John Koleszar's avatar
John Koleszar committed
    else
        x->encode_breakout = cpi->oxcf.encode_breakout;

    if (cpi->sf.RD)
    {
        int zbin_mode_boost_enabled = cpi->zbin_mode_boost_enabled;

        /* Are we using the fast quantizer for the mode selection? */
        if(cpi->sf.use_fastquant_for_pick)
            cpi->mb.quantize_b      = QUANTIZE_INVOKE(&cpi->rtcd.quantize,
                                                      fastquantb);
            cpi->mb.quantize_b_pair = QUANTIZE_INVOKE(&cpi->rtcd.quantize,
                                                      fastquantb_pair);
            /* the fast quantizer does not use zbin_extra, so
             * do not recalculate */
            cpi->zbin_mode_boost_enabled = 0;
        }
        vp8_rd_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate,
                               &distortion, &intra_error);

        /* switch back to the regular quantizer for the encode */
        if (cpi->sf.improved_quant)
        {
            cpi->mb.quantize_b      = QUANTIZE_INVOKE(&cpi->rtcd.quantize,
                                                      quantb);
            cpi->mb.quantize_b_pair = QUANTIZE_INVOKE(&cpi->rtcd.quantize,
                                                      quantb_pair);
        /* restore cpi->zbin_mode_boost_enabled */
        cpi->zbin_mode_boost_enabled = zbin_mode_boost_enabled;

John Koleszar's avatar
John Koleszar committed
    }
    else
        vp8_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate,
                            &distortion, &intra_error);
    cpi->prediction_error += distortion;
John Koleszar's avatar
John Koleszar committed
    cpi->intra_error += intra_error;

    if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
    {
        // Adjust the zbin based on this MB rate.
        adjust_act_zbin( cpi, rate, x );
    }

John Koleszar's avatar
John Koleszar committed
#if 0
    // Experimental RD code
    cpi->frame_distortion += distortion;
    cpi->last_mb_distortion = distortion;
#endif

    // MB level adjutment to quantizer setup
    if (xd->segmentation_enabled)
John Koleszar's avatar
John Koleszar committed
    {
        // If cyclic update enabled
        if (cpi->cyclic_refresh_mode_enabled)
        {
            // Clear segment_id back to 0 if not coded (last frame 0,0)
            if ((xd->mode_info_context->mbmi.segment_id == 1) &&
                ((xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) || (xd->mode_info_context->mbmi.mode != ZEROMV)))
John Koleszar's avatar
John Koleszar committed
            {
                xd->mode_info_context->mbmi.segment_id = 0;

                /* segment_id changed, so update */
                vp8cx_mb_init_quantizer(cpi, x);
        // Experimental code. Special case for gf and arf zeromv modes.
        // Increase zbin size to supress noise
John Koleszar's avatar
John Koleszar committed
        if (cpi->zbin_mode_boost_enabled)
        {
            if ( xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME )
                 cpi->zbin_mode_boost = 0;
John Koleszar's avatar
John Koleszar committed
            else
            {
                if (xd->mode_info_context->mbmi.mode == ZEROMV)
                {
                    if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME)
                        cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
                    else
                        cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
                }
                else if (xd->mode_info_context->mbmi.mode == SPLITMV)
                    cpi->zbin_mode_boost = 0;
                else
                    cpi->zbin_mode_boost = MV_ZBIN_BOOST;
            }
John Koleszar's avatar
John Koleszar committed
        }
        else
            cpi->zbin_mode_boost = 0;
        vp8_update_zbin_extra(cpi, x);
    cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame] ++;
    if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
John Koleszar's avatar
John Koleszar committed
    {
        vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);

        if (xd->mode_info_context->mbmi.mode == B_PRED)
John Koleszar's avatar
John Koleszar committed
        {
            vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
        }
        else
        {
            vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
        }

        sum_intra_stats(cpi, x);
    }
    else
    {
John Koleszar's avatar
John Koleszar committed

        vp8_build_uvmvs(xd, cpi->common.full_pixel);

        if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
            ref_fb_idx = cpi->common.lst_fb_idx;
        else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
            ref_fb_idx = cpi->common.gld_fb_idx;
John Koleszar's avatar
John Koleszar committed
        else
            ref_fb_idx = cpi->common.alt_fb_idx;

        xd->pre.y_buffer = cpi->common.yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
        xd->pre.u_buffer = cpi->common.yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
        xd->pre.v_buffer = cpi->common.yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
Scott LaVarnway's avatar
Scott LaVarnway committed
        if (!x->skip)
John Koleszar's avatar
John Koleszar committed
        {
            vp8_encode_inter16x16(IF_RTCD(&cpi->rtcd), x);

            // Clear mb_skip_coeff if mb_no_coeff_skip is not set
            if (!cpi->common.mb_no_coeff_skip)
                xd->mode_info_context->mbmi.mb_skip_coeff = 0;
            vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
                                           xd->dst.u_buffer, xd->dst.v_buffer,
                                           xd->dst.y_stride, xd->dst.uv_stride);

John Koleszar's avatar
John Koleszar committed
    }

    if (!x->skip)
        vp8_tokenize_mb(cpi, xd, t);
    else
    {
        if (cpi->common.mb_no_coeff_skip)
        {
            xd->mode_info_context->mbmi.mb_skip_coeff = 1;
John Koleszar's avatar
John Koleszar committed
            cpi->skip_true_count ++;
            vp8_fix_contexts(xd);
John Koleszar's avatar
John Koleszar committed
        }
        else
        {
            vp8_stuff_mb(cpi, xd, t);
            xd->mode_info_context->mbmi.mb_skip_coeff = 0;
John Koleszar's avatar
John Koleszar committed
            cpi->skip_false_count ++;
        }
    }

    return rate;
}