1295 lines · 41.9 KB · C
RawDownload
/* *  Copyright (c) 2010 The WebM project authors. All Rights Reserved. * *  Use of this source code is governed by a BSD-style license *  that can be found in the LICENSE file in the root of the source *  tree. An additional intellectual property rights grant can be found *  in the file PATENTS.  All contributing project authors may *  be found in the AUTHORS file in the root of the source tree. */  #include <limits.h>#include "vpx_config.h"#include "onyx_int.h"#include "modecosts.h"#include "encodeintra.h"#include "vp8/common/entropymode.h"#include "pickinter.h"#include "vp8/common/findnearmv.h"#include "encodemb.h"#include "vp8/common/reconinter.h"#include "vp8/common/reconintra4x4.h"#include "vp8/common/variance.h"#include "mcomp.h"#include "rdopt.h"#include "vpx_mem/vpx_mem.h"#if CONFIG_TEMPORAL_DENOISING#include "denoising.h"#endif extern int VP8_UVSSE(MACROBLOCK *x); #ifdef SPEEDSTATSextern unsigned int cnt_pm;#endif extern const int vp8_ref_frame_order[MAX_MODES];extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES]; extern int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]);  int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d,                                int_mv *bestmv, int_mv *ref_mv,                                int error_per_bit,                                const vp8_variance_fn_ptr_t *vfp,                                int *mvcost[2], int *distortion,                                unsigned int *sse){    (void) b;    (void) d;    (void) ref_mv;    (void) error_per_bit;    (void) vfp;    (void) mvcost;    (void) distortion;    (void) sse;    bestmv->as_mv.row <<= 3;    bestmv->as_mv.col <<= 3;    return 0;}  int vp8_get_inter_mbpred_error(MACROBLOCK *mb,                                  const vp8_variance_fn_ptr_t *vfp,                                  unsigned int *sse,                                  int_mv this_mv){     BLOCK *b = &mb->block[0];    BLOCKD *d = &mb->e_mbd.block[0];    unsigned char *what = (*(b->base_src) + b->src);    int what_stride = b->src_stride;    int pre_stride = mb->e_mbd.pre.y_stride;    unsigned char *in_what = mb->e_mbd.pre.y_buffer + d->offset ;    int in_what_stride = pre_stride;    int xoffset = this_mv.as_mv.col & 7;    int yoffset = this_mv.as_mv.row & 7;     in_what += (this_mv.as_mv.row >> 3) * pre_stride + (this_mv.as_mv.col >> 3);     if (xoffset | yoffset)    {        return vfp->svf(in_what, in_what_stride, xoffset, yoffset, what, what_stride, sse);    }    else    {        return vfp->vf(what, what_stride, in_what, in_what_stride, sse);    } }  unsigned int vp8_get4x4sse_cs_c(    const unsigned char *src_ptr,    int  source_stride,    const unsigned char *ref_ptr,    int  recon_stride){    int distortion = 0;    int r, c;     for (r = 0; r < 4; r++)    {        for (c = 0; c < 4; c++)        {            int diff = src_ptr[c] - ref_ptr[c];            distortion += diff * diff;        }         src_ptr += source_stride;        ref_ptr += recon_stride;    }     return distortion;} static int get_prediction_error(BLOCK *be, BLOCKD *b){    unsigned char *sptr;    unsigned char *dptr;    sptr = (*(be->base_src) + be->src);    dptr = b->predictor;     return vp8_get4x4sse_cs(sptr, be->src_stride, dptr, 16); } static int pick_intra4x4block(    MACROBLOCK *x,    int ib,    B_PREDICTION_MODE *best_mode,    const int *mode_costs,     int *bestrate,    int *bestdistortion){     BLOCKD *b = &x->e_mbd.block[ib];    BLOCK *be = &x->block[ib];    int dst_stride = x->e_mbd.dst.y_stride;    unsigned char *dst = x->e_mbd.dst.y_buffer + b->offset;    B_PREDICTION_MODE mode;    int best_rd = INT_MAX;    int rate;    int distortion;     unsigned char *Above = dst - dst_stride;    unsigned char *yleft = dst - 1;    unsigned char top_left = Above[-1];     for (mode = B_DC_PRED; mode <= B_HE_PRED; mode++)    {        int this_rd;         rate = mode_costs[mode];         vp8_intra4x4_predict(Above, yleft, dst_stride, mode,                             b->predictor, 16, top_left);        distortion = get_prediction_error(be, b);        this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);         if (this_rd < best_rd)        {            *bestrate = rate;            *bestdistortion = distortion;            best_rd = this_rd;            *best_mode = mode;        }    }     b->bmi.as_mode = *best_mode;    vp8_encode_intra4x4block(x, ib);    return best_rd;}  static int pick_intra4x4mby_modes(    MACROBLOCK *mb,    int *Rate,    int *best_dist){    MACROBLOCKD *const xd = &mb->e_mbd;    int i;    int cost = mb->mbmode_cost [xd->frame_type] [B_PRED];    int error;    int distortion = 0;    const int *bmode_costs;     intra_prediction_down_copy(xd, xd->dst.y_buffer - xd->dst.y_stride + 16);     bmode_costs = mb->inter_bmode_costs;     for (i = 0; i < 16; i++)    {        MODE_INFO *const mic = xd->mode_info_context;        const int mis = xd->mode_info_stride;         B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);        int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(d);         if (mb->e_mbd.frame_type == KEY_FRAME)        {            const B_PREDICTION_MODE A = above_block_mode(mic, i, mis);            const B_PREDICTION_MODE L = left_block_mode(mic, i);             bmode_costs  = mb->bmode_costs[A][L];        }          pick_intra4x4block(mb, i, &best_mode, bmode_costs, &r, &d);         cost += r;        distortion += d;        mic->bmi[i].as_mode = best_mode;         /* Break out case where we have already exceeded best so far value         * that was passed in         */        if (distortion > *best_dist)            break;    }     *Rate = cost;     if (i == 16)    {        *best_dist = distortion;        error = RDCOST(mb->rdmult, mb->rddiv, cost, distortion);    }    else    {        *best_dist = INT_MAX;        error = INT_MAX;    }     return error;} static void pick_intra_mbuv_mode(MACROBLOCK *mb){     MACROBLOCKD *x = &mb->e_mbd;    unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride;    unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride;    unsigned char *usrc_ptr = (mb->block[16].src + *mb->block[16].base_src);    unsigned char *vsrc_ptr = (mb->block[20].src + *mb->block[20].base_src);    int uvsrc_stride = mb->block[16].src_stride;    unsigned char uleft_col[8];    unsigned char vleft_col[8];    unsigned char utop_left = uabove_row[-1];    unsigned char vtop_left = vabove_row[-1];    int i, j;    int expected_udc;    int expected_vdc;    int shift;    int Uaverage = 0;    int Vaverage = 0;    int diff;    int pred_error[4] = {0, 0, 0, 0}, best_error = INT_MAX;    MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);      for (i = 0; i < 8; i++)    {        uleft_col[i] = x->dst.u_buffer [i* x->dst.uv_stride -1];        vleft_col[i] = x->dst.v_buffer [i* x->dst.uv_stride -1];    }     if (!x->up_available && !x->left_available)    {        expected_udc = 128;        expected_vdc = 128;    }    else    {        shift = 2;         if (x->up_available)        {             for (i = 0; i < 8; i++)            {                Uaverage += uabove_row[i];                Vaverage += vabove_row[i];            }             shift ++;         }         if (x->left_available)        {            for (i = 0; i < 8; i++)            {                Uaverage += uleft_col[i];                Vaverage += vleft_col[i];            }             shift ++;         }         expected_udc = (Uaverage + (1 << (shift - 1))) >> shift;        expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift;    }      for (i = 0; i < 8; i++)    {        for (j = 0; j < 8; j++)        {             int predu = uleft_col[i] + uabove_row[j] - utop_left;            int predv = vleft_col[i] + vabove_row[j] - vtop_left;            int u_p, v_p;             u_p = usrc_ptr[j];            v_p = vsrc_ptr[j];             if (predu < 0)                predu = 0;             if (predu > 255)                predu = 255;             if (predv < 0)                predv = 0;             if (predv > 255)                predv = 255;              diff = u_p - expected_udc;            pred_error[DC_PRED] += diff * diff;            diff = v_p - expected_vdc;            pred_error[DC_PRED] += diff * diff;              diff = u_p - uabove_row[j];            pred_error[V_PRED] += diff * diff;            diff = v_p - vabove_row[j];            pred_error[V_PRED] += diff * diff;              diff = u_p - uleft_col[i];            pred_error[H_PRED] += diff * diff;            diff = v_p - vleft_col[i];            pred_error[H_PRED] += diff * diff;              diff = u_p - predu;            pred_error[TM_PRED] += diff * diff;            diff = v_p - predv;            pred_error[TM_PRED] += diff * diff;          }         usrc_ptr += uvsrc_stride;        vsrc_ptr += uvsrc_stride;         if (i == 3)        {            usrc_ptr = (mb->block[18].src + *mb->block[18].base_src);            vsrc_ptr = (mb->block[22].src + *mb->block[22].base_src);        }       }      for (i = DC_PRED; i <= TM_PRED; i++)    {        if (best_error > pred_error[i])        {            best_error = pred_error[i];            best_mode = (MB_PREDICTION_MODE)i;        }    }      mb->e_mbd.mode_info_context->mbmi.uv_mode = best_mode; } static void update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv){    MACROBLOCKD *xd = &x->e_mbd;    /* Split MV modes currently not supported when RD is nopt enabled,     * therefore, only need to modify MVcount in NEWMV mode. */    if (xd->mode_info_context->mbmi.mode == NEWMV)    {        x->MVcount[0][mv_max+((xd->mode_info_context->mbmi.mv.as_mv.row -                                      best_ref_mv->as_mv.row) >> 1)]++;        x->MVcount[1][mv_max+((xd->mode_info_context->mbmi.mv.as_mv.col -                                      best_ref_mv->as_mv.col) >> 1)]++;    }}  #if CONFIG_MULTI_RES_ENCODINGstaticvoid get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd, int *dissim,                               int *parent_ref_frame,                               MB_PREDICTION_MODE *parent_mode,                               int_mv *parent_ref_mv, int mb_row, int mb_col){    LOWER_RES_MB_INFO* store_mode_info                          = ((LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info)->mb_info;    unsigned int parent_mb_index;     /* Consider different down_sampling_factor.  */    {        /* TODO: Removed the loop that supports special down_sampling_factor         * such as 2, 4, 8. Will revisit it if needed.         * Should also try using a look-up table to see if it helps         * performance. */        int parent_mb_row, parent_mb_col;         parent_mb_row = mb_row*cpi->oxcf.mr_down_sampling_factor.den                    /cpi->oxcf.mr_down_sampling_factor.num;        parent_mb_col = mb_col*cpi->oxcf.mr_down_sampling_factor.den                    /cpi->oxcf.mr_down_sampling_factor.num;        parent_mb_index = parent_mb_row*cpi->mr_low_res_mb_cols + parent_mb_col;    }     /* Read lower-resolution mode & motion result from memory.*/    *parent_ref_frame = store_mode_info[parent_mb_index].ref_frame;    *parent_mode =  store_mode_info[parent_mb_index].mode;    *dissim = store_mode_info[parent_mb_index].dissim;     /* For highest-resolution encoder, adjust dissim value. Lower its quality     * for good performance. */    if (cpi->oxcf.mr_encoder_id == (cpi->oxcf.mr_total_resolutions - 1))        *dissim>>=1;     if(*parent_ref_frame != INTRA_FRAME)    {        /* Consider different down_sampling_factor.         * The result can be rounded to be more precise, but it takes more time.         */        (*parent_ref_mv).as_mv.row = store_mode_info[parent_mb_index].mv.as_mv.row                                  *cpi->oxcf.mr_down_sampling_factor.num                                  /cpi->oxcf.mr_down_sampling_factor.den;        (*parent_ref_mv).as_mv.col = store_mode_info[parent_mb_index].mv.as_mv.col                                  *cpi->oxcf.mr_down_sampling_factor.num                                  /cpi->oxcf.mr_down_sampling_factor.den;         vp8_clamp_mv2(parent_ref_mv, xd);    }}#endif static void check_for_encode_breakout(unsigned int sse, MACROBLOCK* x){    MACROBLOCKD *xd = &x->e_mbd;     unsigned int threshold = (xd->block[0].dequant[1]        * xd->block[0].dequant[1] >>4);     if(threshold < x->encode_breakout)        threshold = x->encode_breakout;     if (sse < threshold )    {        /* Check u and v to make sure skip is ok */        unsigned int sse2 = 0;         sse2 = VP8_UVSSE(x);         if (sse2 * 2 < x->encode_breakout)            x->skip = 1;        else            x->skip = 0;    }} static int evaluate_inter_mode(unsigned int* sse, int rate2, int* distortion2,                               VP8_COMP *cpi, MACROBLOCK *x, int rd_adj){    MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode;    int_mv mv = x->e_mbd.mode_info_context->mbmi.mv;    int this_rd;    /* Exit early and don't compute the distortion if this macroblock     * is marked inactive. */    if (cpi->active_map_enabled && x->active_ptr[0] == 0)    {        *sse = 0;        *distortion2 = 0;        x->skip = 1;        return INT_MAX;    }     if((this_mode != NEWMV) ||

Lines 1–500 of 1295.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t