diff options
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/common/vp9_alloccommon.c | 133 | ||||
-rw-r--r-- | vp9/common/vp9_reconinter.c | 47 | ||||
-rw-r--r-- | vp9/encoder/vp9_block.h | 1 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 94 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodemb.c | 1 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodemv.c | 22 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodemv.h | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_firstpass.c | 7 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_if.c | 124 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_int.h | 19 | ||||
-rw-r--r-- | vp9/encoder/vp9_pickmode.c | 36 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 19 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.h | 5 | ||||
-rw-r--r-- | vp9/vp9_cx_iface.c | 4 |
14 files changed, 250 insertions, 265 deletions
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c index 920aefa79..08ab27a8c 100644 --- a/vp9/common/vp9_alloccommon.c +++ b/vp9/common/vp9_alloccommon.c @@ -8,7 +8,6 @@ * be found in the AUTHORS file in the root of the source tree. */ - #include "./vpx_config.h" #include "vpx_mem/vpx_mem.h" @@ -30,34 +29,6 @@ void vp9_update_mode_info_border(VP9_COMMON *cm, MODE_INFO *mi) { vpx_memset(&mi[i * stride], 0, sizeof(MODE_INFO)); } -void vp9_free_frame_buffers(VP9_COMMON *cm) { - int i; - - for (i = 0; i < FRAME_BUFFERS; i++) { - vp9_free_frame_buffer(&cm->frame_bufs[i].buf); - - if (cm->frame_bufs[i].ref_count > 0 && - cm->frame_bufs[i].raw_frame_buffer.data != NULL) { - cm->release_fb_cb(cm->cb_priv, &cm->frame_bufs[i].raw_frame_buffer); - cm->frame_bufs[i].ref_count = 0; - } - } - - vp9_free_frame_buffer(&cm->post_proc_buffer); - - vpx_free(cm->mip); - vpx_free(cm->prev_mip); - vpx_free(cm->last_frame_seg_map); - vpx_free(cm->mi_grid_base); - vpx_free(cm->prev_mi_grid_base); - - cm->mip = NULL; - cm->prev_mip = NULL; - cm->last_frame_seg_map = NULL; - cm->mi_grid_base = NULL; - cm->prev_mi_grid_base = NULL; -} - static void set_mb_mi(VP9_COMMON *cm, int aligned_width, int aligned_height) { cm->mi_cols = aligned_width >> MI_SIZE_LOG2; cm->mi_rows = aligned_height >> MI_SIZE_LOG2; @@ -75,7 +46,7 @@ static void setup_mi(VP9_COMMON *cm) { cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; vpx_memset(cm->mip, 0, - cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO)); + cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(*cm->mip)); vpx_memset(cm->mi_grid_base, 0, cm->mode_info_stride * (cm->mi_rows + 1) * @@ -84,12 +55,66 @@ static void setup_mi(VP9_COMMON *cm) { vp9_update_mode_info_border(cm, cm->prev_mip); } +static int alloc_mi(VP9_COMMON *cm, int mi_size) { + cm->mip = (MODE_INFO *)vpx_calloc(mi_size, sizeof(*cm->mip)); + if (cm->mip == NULL) + return 1; + + cm->prev_mip = (MODE_INFO *)vpx_calloc(mi_size, sizeof(*cm->prev_mip)); + if (cm->prev_mip == NULL) + return 1; + + cm->mi_grid_base = + (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->mi_grid_base)); + if (cm->mi_grid_base == NULL) + return 1; + + cm->prev_mi_grid_base = + (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base)); + if (cm->prev_mi_grid_base == NULL) + return 1; + + return 0; +} + +static void free_mi(VP9_COMMON *cm) { + vpx_free(cm->mip); + vpx_free(cm->prev_mip); + vpx_free(cm->mi_grid_base); + vpx_free(cm->prev_mi_grid_base); + + cm->mip = NULL; + cm->prev_mip = NULL; + cm->mi_grid_base = NULL; + cm->prev_mi_grid_base = NULL; +} + +void vp9_free_frame_buffers(VP9_COMMON *cm) { + int i; + + for (i = 0; i < FRAME_BUFFERS; ++i) { + vp9_free_frame_buffer(&cm->frame_bufs[i].buf); + + if (cm->frame_bufs[i].ref_count > 0 && + cm->frame_bufs[i].raw_frame_buffer.data != NULL) { + cm->release_fb_cb(cm->cb_priv, &cm->frame_bufs[i].raw_frame_buffer); + cm->frame_bufs[i].ref_count = 0; + } + } + + vp9_free_frame_buffer(&cm->post_proc_buffer); + + free_mi(cm); + + vpx_free(cm->last_frame_seg_map); + cm->last_frame_seg_map = NULL; +} + int vp9_resize_frame_buffers(VP9_COMMON *cm, int width, int height) { const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2); const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2); const int ss_x = cm->subsampling_x; const int ss_y = cm->subsampling_y; - int mi_size; if (vp9_realloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y, VP9_DEC_BORDER_IN_PIXELS, NULL, NULL, NULL) < 0) @@ -97,29 +122,8 @@ int vp9_resize_frame_buffers(VP9_COMMON *cm, int width, int height) { set_mb_mi(cm, aligned_width, aligned_height); - // Allocation - mi_size = cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE); - - vpx_free(cm->mip); - cm->mip = (MODE_INFO *)vpx_calloc(mi_size, sizeof(MODE_INFO)); - if (!cm->mip) - goto fail; - - vpx_free(cm->prev_mip); - cm->prev_mip = (MODE_INFO *)vpx_calloc(mi_size, sizeof(MODE_INFO)); - if (!cm->prev_mip) - goto fail; - - vpx_free(cm->mi_grid_base); - cm->mi_grid_base = - (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->mi_grid_base)); - if (!cm->mi_grid_base) - goto fail; - - vpx_free(cm->prev_mi_grid_base); - cm->prev_mi_grid_base = - (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base)); - if (!cm->prev_mi_grid_base) + free_mi(cm); + if (alloc_mi(cm, cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE))) goto fail; setup_mi(cm); @@ -144,7 +148,6 @@ int vp9_alloc_frame_buffers(VP9_COMMON *cm, int width, int height) { const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2); const int ss_x = cm->subsampling_x; const int ss_y = cm->subsampling_y; - int mi_size; vp9_free_frame_buffers(cm); @@ -169,25 +172,7 @@ int vp9_alloc_frame_buffers(VP9_COMMON *cm, int width, int height) { set_mb_mi(cm, aligned_width, aligned_height); - // Allocation - mi_size = cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE); - - cm->mip = (MODE_INFO *)vpx_calloc(mi_size, sizeof(MODE_INFO)); - if (!cm->mip) - goto fail; - - cm->prev_mip = (MODE_INFO *)vpx_calloc(mi_size, sizeof(MODE_INFO)); - if (!cm->prev_mip) - goto fail; - - cm->mi_grid_base = - (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->mi_grid_base)); - if (!cm->mi_grid_base) - goto fail; - - cm->prev_mi_grid_base = - (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base)); - if (!cm->prev_mi_grid_base) + if (alloc_mi(cm, cm->mode_info_stride * (cm->mi_rows + MI_BLOCK_SIZE))) goto fail; setup_mi(cm); diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index 86548750e..005f370a0 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -293,24 +293,40 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block, ref_frame = plane == 1 ? ref_buf->u_buffer : ref_buf->v_buffer; } - // Get block position in current frame. - x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; - y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; + if (vp9_is_scaled(sf)) { + // Co-ordinate of containing block to pixel precision. + int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)); + int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)); - // Precision of x0_16 and y0_16 is 1/16th pixel. - x0_16 = x0 << SUBPEL_BITS; - y0_16 = y0 << SUBPEL_BITS; + // Co-ordinate of the block to 1/16th pixel precision. + x0_16 = (x_start + x) << SUBPEL_BITS; + y0_16 = (y_start + y) << SUBPEL_BITS; - if (vp9_is_scaled(sf)) { + // Co-ordinate of current block in reference frame + // to 1/16th pixel precision. + x0_16 = sf->scale_value_x(x0_16, sf); + y0_16 = sf->scale_value_y(y0_16, sf); + + // Map the top left corner of the block into the reference frame. + // NOTE: This must be done in this way instead of + // sf->scale_value_x(x_start + x, sf). + x0 = sf->scale_value_x(x_start, sf) + sf->scale_value_x(x, sf); + y0 = sf->scale_value_y(y_start, sf) + sf->scale_value_y(y, sf); + + // Scale the MV and incorporate the sub-pixel offset of the block + // in the reference frame. scaled_mv = vp9_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); xs = sf->x_step_q4; ys = sf->y_step_q4; - // Map the top left corner of the block into the reference frame. - x0 = sf->scale_value_x(x0, sf); - y0 = sf->scale_value_y(y0, sf); - x0_16 = sf->scale_value_x(x0_16, sf); - y0_16 = sf->scale_value_y(y0_16, sf); } else { + // Co-ordinate of containing block to pixel precision. + x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; + y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; + + // Co-ordinate of the block to 1/16th pixel precision. + x0_16 = x0 << SUBPEL_BITS; + y0_16 = y0 << SUBPEL_BITS; + scaled_mv.row = mv_q4.row; scaled_mv.col = mv_q4.col; xs = ys = 16; @@ -354,9 +370,10 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block, y0 < 0 || y0 > frame_height - 1 || y1 < 0 || y1 > frame_height - 1) { uint8_t *buf_ptr1 = ref_frame + y0 * pre_buf->stride + x0; // Extend the border. - build_mc_border(buf_ptr1, pre_buf->stride, xd->mc_buf, x1 - x0, - x0, y0, x1 - x0, y1 - y0, frame_width, frame_height); - buf_stride = x1 - x0; + build_mc_border(buf_ptr1, pre_buf->stride, xd->mc_buf, x1 - x0 + 1, + x0, y0, x1 - x0 + 1, y1 - y0 + 1, frame_width, + frame_height); + buf_stride = x1 - x0 + 1; buf_ptr = xd->mc_buf + y_pad * 3 * buf_stride + x_pad * 3; } } diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h index 168702e90..888984cce 100644 --- a/vp9/encoder/vp9_block.h +++ b/vp9/encoder/vp9_block.h @@ -115,7 +115,6 @@ struct macroblock { unsigned int source_variance; unsigned int pred_sse[MAX_REF_FRAMES]; int pred_mv_sad[MAX_REF_FRAMES]; - int mode_sad[MAX_REF_FRAMES][INTER_MODES + 1]; int nmvjointcost[MV_JOINTS]; int nmvcosts[2][MV_VALS]; diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 87ebc3de0..2f6c33d90 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -985,12 +985,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, #endif if (!frame_is_intra_only(cm)) { if (is_inter_block(mbmi)) { - if (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV) { - MV best_mv[2]; - for (i = 0; i < 1 + has_second_ref(mbmi); ++i) - best_mv[i] = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_mv; - vp9_update_mv_count(cm, xd, best_mv); - } + vp9_update_mv_count(cm, xd); if (cm->interp_filter == SWITCHABLE) { const int ctx = vp9_get_pred_context_switchable_interp(xd); @@ -1462,14 +1457,16 @@ static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) { static void update_state_rt(VP9_COMP *cpi, const PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col, int bsize) { - int i; VP9_COMMON *const cm = &cpi->common; MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; const struct segmentation *const seg = &cm->seg; - x->skip = ctx->skip; + // TODO(jingning) We might need PICK_MODE_CONTEXT to buffer coding modes + // associated with variable block sizes. Otherwise, remove this ctx + // from argument list. + (void)ctx; // Check for reseting segment_id and update cyclic map. if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && seg->enabled) { @@ -1477,39 +1474,12 @@ static void update_state_rt(VP9_COMP *cpi, const PICK_MODE_CONTEXT *ctx, vp9_init_plane_quantizers(cpi, x); } -#if CONFIG_INTERNAL_STATS - if (frame_is_intra_only(cm)) { - static const int kf_mode_index[] = { - THR_DC /*DC_PRED*/, - THR_V_PRED /*V_PRED*/, - THR_H_PRED /*H_PRED*/, - THR_D45_PRED /*D45_PRED*/, - THR_D135_PRED /*D135_PRED*/, - THR_D117_PRED /*D117_PRED*/, - THR_D153_PRED /*D153_PRED*/, - THR_D207_PRED /*D207_PRED*/, - THR_D63_PRED /*D63_PRED*/, - THR_TM /*TM_PRED*/, - }; - ++cpi->mode_chosen_counts[kf_mode_index[mbmi->mode]]; - } else { - // Note how often each mode chosen as best - ++cpi->mode_chosen_counts[ctx->best_mode_index]; - } -#endif - if (!frame_is_intra_only(cm)) { - if (is_inter_block(mbmi)) { - if (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV) { - MV best_mv[2]; - for (i = 0; i < 1 + has_second_ref(mbmi); ++i) - best_mv[i] = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_mv; - vp9_update_mv_count(cm, xd, best_mv); - } + if (is_inter_block(mbmi)) { + vp9_update_mv_count(cm, xd); - if (cm->interp_filter == SWITCHABLE) { - const int pred_ctx = vp9_get_pred_context_switchable_interp(xd); - ++cm->counts.switchable_interp[pred_ctx][mbmi->interp_filter]; - } + if (cm->interp_filter == SWITCHABLE) { + const int pred_ctx = vp9_get_pred_context_switchable_interp(xd); + ++cm->counts.switchable_interp[pred_ctx][mbmi->interp_filter]; } } } @@ -2711,6 +2681,7 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, MACROBLOCKD *const xd = &x->e_mbd; set_offsets(cpi, tile, mi_row, mi_col, bsize); xd->mi_8x8[0]->mbmi.sb_type = bsize; + if (!frame_is_intra_only(cm)) { vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col, rate, dist, bsize); @@ -2843,6 +2814,8 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, int64_t dummy_dist; const int idx_str = cm->mode_info_stride * mi_row + mi_col; MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; + MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; + BLOCK_SIZE bsize = cpi->sf.partition_search_type == FIXED_PARTITION ? cpi->sf.always_this_block_size : get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col); @@ -2852,6 +2825,47 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, // Set the partition type of the 64X64 block if (cpi->sf.partition_search_type == VAR_BASED_PARTITION) choose_partitioning(cpi, tile, mi_row, mi_col); + else if (cpi->sf.partition_search_type == REFERENCE_PARTITION) { + if (cpi->sf.partition_check) { + MACROBLOCK *x = &cpi->mb; + int rate1, rate2, rate3; + int64_t dist1, dist2, dist3; + set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, BLOCK_8X8); + nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, + 0, &rate1, &dist1); + set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, BLOCK_16X16); + nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, + 0, &rate2, &dist2); + set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, BLOCK_32X32); + nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, + 0, &rate3, &dist3); + + if (RDCOST(x->rdmult, x->rddiv, rate1, dist1) < + RDCOST(x->rdmult, x->rddiv, rate2, dist2)) { + if (RDCOST(x->rdmult, x->rddiv, rate1, dist1) < + RDCOST(x->rdmult, x->rddiv, rate3, dist3)) + set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, + BLOCK_8X8); + else + set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, + BLOCK_32X32); + } else { + if (RDCOST(x->rdmult, x->rddiv, rate2, dist2) < + RDCOST(x->rdmult, x->rddiv, rate3, dist3)) + set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, + BLOCK_16X16); + else + set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, + BLOCK_32X32); + } + + } else { + if (!sb_has_motion(cm, prev_mi_8x8)) + copy_partitioning(cm, mi_8x8, prev_mi_8x8); + else + set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize); + } + } else set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize); diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c index 8dbd1a460..fae03bf55 100644 --- a/vp9/encoder/vp9_encodemb.c +++ b/vp9/encoder/vp9_encodemb.c @@ -424,6 +424,7 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize, assert(0 && "Invalid transform size"); } } + static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) { MACROBLOCK *const x = (MACROBLOCK *)arg; diff --git a/vp9/encoder/vp9_encodemv.c b/vp9/encoder/vp9_encodemv.c index 703dde323..2a10bbfde 100644 --- a/vp9/encoder/vp9_encodemv.c +++ b/vp9/encoder/vp9_encodemv.c @@ -229,22 +229,21 @@ void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2], build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], usehp); } -static void inc_mvs(const int_mv mv[2], const MV ref[2], int is_compound, +static void inc_mvs(const MB_MODE_INFO *mbmi, const int_mv mvs[2], nmv_context_counts *counts) { int i; - for (i = 0; i < 1 + is_compound; ++i) { - const MV diff = { mv[i].as_mv.row - ref[i].row, - mv[i].as_mv.col - ref[i].col }; + + for (i = 0; i < 1 + has_second_ref(mbmi); ++i) { + const MV *ref = &mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_mv; + const MV diff = {mvs[i].as_mv.row - ref->row, + mvs[i].as_mv.col - ref->col}; vp9_inc_mv(&diff, counts); } } -void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd, - const MV best_ref_mv[2]) { +void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd) { const MODE_INFO *mi = xd->mi_8x8[0]; const MB_MODE_INFO *const mbmi = &mi->mbmi; - const int is_compound = has_second_ref(mbmi); - nmv_context_counts *counts = &cm->counts.mv; if (mbmi->sb_type < BLOCK_8X8) { const int num_4x4_w = num_4x4_blocks_wide_lookup[mbmi->sb_type]; @@ -255,11 +254,12 @@ void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd, for (idx = 0; idx < 2; idx += num_4x4_w) { const int i = idy * 2 + idx; if (mi->bmi[i].as_mode == NEWMV) - inc_mvs(mi->bmi[i].as_mv, best_ref_mv, is_compound, counts); + inc_mvs(mbmi, mi->bmi[i].as_mv, &cm->counts.mv); } } - } else if (mbmi->mode == NEWMV) { - inc_mvs(mbmi->mv, best_ref_mv, is_compound, counts); + } else { + if (mbmi->mode == NEWMV) + inc_mvs(mbmi, mbmi->mv, &cm->counts.mv); } } diff --git a/vp9/encoder/vp9_encodemv.h b/vp9/encoder/vp9_encodemv.h index f16b2c17c..50cb9611b 100644 --- a/vp9/encoder/vp9_encodemv.h +++ b/vp9/encoder/vp9_encodemv.h @@ -28,8 +28,7 @@ void vp9_encode_mv(VP9_COMP *cpi, vp9_writer* w, const MV* mv, const MV* ref, void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2], const nmv_context* mvctx, int usehp); -void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd, - const MV best_ref_mv[2]); +void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd); #ifdef __cplusplus } // extern "C" diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index cd4e3d670..8167d43a8 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -56,6 +56,13 @@ #define DISABLE_RC_LONG_TERM_MEM 0 +#if CONFIG_MULTIPLE_ARF +// Set MIN_GF_INTERVAL to 1 for the full decomposition. +#define MIN_GF_INTERVAL 2 +#else +#define MIN_GF_INTERVAL 4 +#endif + static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) { YV12_BUFFER_CONFIG temp = *a; *a = *b; diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index ca91a67d5..15a025e75 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -294,9 +294,10 @@ static void setup_in_frame_q_adj(VP9_COMP *cpi) { } static void configure_static_seg_features(VP9_COMP *cpi) { VP9_COMMON *const cm = &cpi->common; + const RATE_CONTROL *const rc = &cpi->rc; struct segmentation *const seg = &cm->seg; - int high_q = (int)(cpi->rc.avg_q > 48.0); + int high_q = (int)(rc->avg_q > 48.0); int qi_delta; // Disable and clear down for KF @@ -334,9 +335,8 @@ static void configure_static_seg_features(VP9_COMP *cpi) { seg->update_map = 1; seg->update_data = 1; - qi_delta = vp9_compute_qdelta( - cpi, cpi->rc.avg_q, (cpi->rc.avg_q * 0.875)); - vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, (qi_delta - 2)); + qi_delta = vp9_compute_qdelta(cpi, rc->avg_q, rc->avg_q * 0.875); + vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2); vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2); vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q); @@ -349,16 +349,15 @@ static void configure_static_seg_features(VP9_COMP *cpi) { // All other frames if segmentation has been enabled // First normal frame in a valid gf or alt ref group - if (cpi->rc.frames_since_golden == 0) { + if (rc->frames_since_golden == 0) { // Set up segment features for normal frames in an arf group - if (cpi->rc.source_alt_ref_active) { + if (rc->source_alt_ref_active) { seg->update_map = 0; seg->update_data = 1; seg->abs_delta = SEGMENT_DELTADATA; - qi_delta = vp9_compute_qdelta(cpi, cpi->rc.avg_q, - (cpi->rc.avg_q * 1.125)); - vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, (qi_delta + 2)); + qi_delta = vp9_compute_qdelta(cpi, rc->avg_q, rc->avg_q * 1.125); + vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2); vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q); vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2); @@ -383,7 +382,7 @@ static void configure_static_seg_features(VP9_COMP *cpi) { vp9_clearall_segfeatures(seg); } - } else if (cpi->rc.is_src_frame_alt_ref) { + } else if (rc->is_src_frame_alt_ref) { // Special case where we are coding over the top of a previous // alt ref frame. // Segment coding disabled for compred testing @@ -874,8 +873,11 @@ static void set_rt_speed_feature(VP9_COMMON *cm, sf->max_intra_bsize = BLOCK_32X32; } if (speed >= 6) { - sf->partition_search_type = VAR_BASED_FIXED_PARTITION; - sf->search_method = HEX; + sf->partition_check = + (cm->current_video_frame % sf->last_partitioning_redo_frequency == 1); + sf->partition_search_type = REFERENCE_PARTITION; + sf->use_nonrd_pick_mode = 1; + sf->search_method = FAST_DIAMOND; } if (speed >= 7) { sf->partition_search_type = VAR_BASED_FIXED_PARTITION; @@ -1211,6 +1213,7 @@ static void set_tile_limits(VP9_COMP *cpi) { static void init_config(struct VP9_COMP *cpi, VP9_CONFIG *oxcf) { VP9_COMMON *const cm = &cpi->common; + RATE_CONTROL *const rc = &cpi->rc; int i; cpi->oxcf = *oxcf; @@ -1238,32 +1241,32 @@ static void init_config(struct VP9_COMP *cpi, VP9_CONFIG *oxcf) { // Initialize active best and worst q and average q values. if (cpi->pass == 0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - cpi->rc.avg_frame_qindex[0] = cpi->oxcf.worst_allowed_q; - cpi->rc.avg_frame_qindex[1] = cpi->oxcf.worst_allowed_q; - cpi->rc.avg_frame_qindex[2] = cpi->oxcf.worst_allowed_q; + rc->avg_frame_qindex[0] = cpi->oxcf.worst_allowed_q; + rc->avg_frame_qindex[1] = cpi->oxcf.worst_allowed_q; + rc->avg_frame_qindex[2] = cpi->oxcf.worst_allowed_q; } else { - cpi->rc.avg_frame_qindex[0] = (cpi->oxcf.worst_allowed_q + - cpi->oxcf.best_allowed_q) / 2; - cpi->rc.avg_frame_qindex[1] = (cpi->oxcf.worst_allowed_q + - cpi->oxcf.best_allowed_q) / 2; - cpi->rc.avg_frame_qindex[2] = (cpi->oxcf.worst_allowed_q + - cpi->oxcf.best_allowed_q) / 2; + rc->avg_frame_qindex[0] = (cpi->oxcf.worst_allowed_q + + cpi->oxcf.best_allowed_q) / 2; + rc->avg_frame_qindex[1] = (cpi->oxcf.worst_allowed_q + + cpi->oxcf.best_allowed_q) / 2; + rc->avg_frame_qindex[2] = (cpi->oxcf.worst_allowed_q + + cpi->oxcf.best_allowed_q) / 2; } - cpi->rc.last_q[0] = cpi->oxcf.best_allowed_q; - cpi->rc.last_q[1] = cpi->oxcf.best_allowed_q; - cpi->rc.last_q[2] = cpi->oxcf.best_allowed_q; + rc->last_q[0] = cpi->oxcf.best_allowed_q; + rc->last_q[1] = cpi->oxcf.best_allowed_q; + rc->last_q[2] = cpi->oxcf.best_allowed_q; // Initialise the starting buffer levels - cpi->rc.buffer_level = cpi->oxcf.starting_buffer_level; - cpi->rc.bits_off_target = cpi->oxcf.starting_buffer_level; + rc->buffer_level = cpi->oxcf.starting_buffer_level; + rc->bits_off_target = cpi->oxcf.starting_buffer_level; - cpi->rc.rolling_target_bits = cpi->rc.av_per_frame_bandwidth; - cpi->rc.rolling_actual_bits = cpi->rc.av_per_frame_bandwidth; - cpi->rc.long_rolling_target_bits = cpi->rc.av_per_frame_bandwidth; - cpi->rc.long_rolling_actual_bits = cpi->rc.av_per_frame_bandwidth; + rc->rolling_target_bits = rc->av_per_frame_bandwidth; + rc->rolling_actual_bits = rc->av_per_frame_bandwidth; + rc->long_rolling_target_bits = rc->av_per_frame_bandwidth; + rc->long_rolling_actual_bits = rc->av_per_frame_bandwidth; - cpi->rc.total_actual_bits = 0; - cpi->rc.total_target_vs_actual = 0; + rc->total_actual_bits = 0; + rc->total_target_vs_actual = 0; cpi->static_mb_pct = 0; @@ -1606,8 +1609,9 @@ static void free_pick_mode_context(MACROBLOCK *x) { VP9_COMP *vp9_create_compressor(VP9_CONFIG *oxcf) { int i, j; - VP9_COMP *cpi = vpx_memalign(32, sizeof(VP9_COMP)); - VP9_COMMON *cm = cpi != NULL ? &cpi->common : NULL; + VP9_COMP *const cpi = vpx_memalign(32, sizeof(VP9_COMP)); + VP9_COMMON *const cm = cpi != NULL ? &cpi->common : NULL; + RATE_CONTROL *const rc = cpi != NULL ? &cpi->rc : NULL; if (!cm) return NULL; @@ -1637,7 +1641,7 @@ VP9_COMP *vp9_create_compressor(VP9_CONFIG *oxcf) { // Set reference frame sign bias for ALTREF frame to 1 (for now) cm->ref_frame_sign_bias[ALTREF_FRAME] = 1; - cpi->rc.baseline_gf_interval = DEFAULT_GF_INTERVAL; + rc->baseline_gf_interval = DEFAULT_GF_INTERVAL; cpi->gold_is_last = 0; cpi->alt_is_last = 0; @@ -1675,12 +1679,12 @@ VP9_COMP *vp9_create_compressor(VP9_CONFIG *oxcf) { cpi->activity_avg = 90 << 12; cpi->key_frame_frequency = cpi->oxcf.key_freq; - cpi->rc.frames_since_key = 8; // Sensible default for first frame. - cpi->rc.this_key_frame_forced = 0; - cpi->rc.next_key_frame_forced = 0; + rc->frames_since_key = 8; // Sensible default for first frame. + rc->this_key_frame_forced = 0; + rc->next_key_frame_forced = 0; - cpi->rc.source_alt_ref_pending = 0; - cpi->rc.source_alt_ref_active = 0; + rc->source_alt_ref_pending = 0; + rc->source_alt_ref_active = 0; cpi->refresh_alt_ref_frame = 0; #if CONFIG_MULTIPLE_ARF @@ -1736,17 +1740,17 @@ VP9_COMP *vp9_create_compressor(VP9_CONFIG *oxcf) { cpi->first_time_stamp_ever = INT64_MAX; - cpi->rc.frames_till_gf_update_due = 0; + rc->frames_till_gf_update_due = 0; - cpi->rc.ni_av_qi = cpi->oxcf.worst_allowed_q; - cpi->rc.ni_tot_qi = 0; - cpi->rc.ni_frames = 0; - cpi->rc.tot_q = 0.0; - cpi->rc.avg_q = vp9_convert_qindex_to_q(cpi->oxcf.worst_allowed_q); + rc->ni_av_qi = cpi->oxcf.worst_allowed_q; + rc->ni_tot_qi = 0; + rc->ni_frames = 0; + rc->tot_q = 0.0; + rc->avg_q = vp9_convert_qindex_to_q(cpi->oxcf.worst_allowed_q); - cpi->rc.rate_correction_factor = 1.0; - cpi->rc.key_frame_rate_correction_factor = 1.0; - cpi->rc.gf_rate_correction_factor = 1.0; + rc->rate_correction_factor = 1.0; + rc->key_frame_rate_correction_factor = 1.0; + rc->gf_rate_correction_factor = 1.0; cal_nmvjointsadcost(cpi->mb.nmvjointsadcost); cpi->mb.nmvcost[0] = &cpi->mb.nmvcosts[0][MV_MAX]; @@ -2155,25 +2159,11 @@ int vp9_use_as_reference(VP9_COMP *cpi, int ref_frame_flags) { return 0; } -int vp9_update_reference(VP9_COMP *cpi, int ref_frame_flags) { - if (ref_frame_flags > 7) - return -1; - - cpi->ext_refresh_golden_frame = 0; - cpi->ext_refresh_alt_ref_frame = 0; - cpi->ext_refresh_last_frame = 0; - - if (ref_frame_flags & VP9_LAST_FLAG) - cpi->ext_refresh_last_frame = 1; - - if (ref_frame_flags & VP9_GOLD_FLAG) - cpi->ext_refresh_golden_frame = 1; - - if (ref_frame_flags & VP9_ALT_FLAG) - cpi->ext_refresh_alt_ref_frame = 1; - +void vp9_update_reference(VP9_COMP *cpi, int ref_frame_flags) { + cpi->ext_refresh_golden_frame = (ref_frame_flags & VP9_GOLD_FLAG) != 0; + cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & VP9_ALT_FLAG) != 0; + cpi->ext_refresh_last_frame = (ref_frame_flags & VP9_LAST_FLAG) != 0; cpi->ext_refresh_frame_flags_pending = 1; - return 0; } static YV12_BUFFER_CONFIG *get_vp9_ref_frame_buffer(VP9_COMP *cpi, diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index ad1dd9b2a..d46e2e18b 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -40,22 +40,11 @@ extern "C" { // #define MODE_TEST_HIT_STATS -#if CONFIG_MULTIPLE_ARF -// Set MIN_GF_INTERVAL to 1 for the full decomposition. -#define MIN_GF_INTERVAL 2 -#else -#define MIN_GF_INTERVAL 4 -#endif #define DEFAULT_GF_INTERVAL 10 -#define KEY_FRAME_CONTEXT 5 - #define MAX_MODES 30 #define MAX_REFS 6 -#define MIN_THRESHMULT 32 -#define MAX_THRESHMULT 512 - typedef struct { int nmvjointcost[MV_JOINTS]; int nmvcosts[2][MV_VALS]; @@ -213,6 +202,8 @@ typedef enum { // determined based on source variance VAR_BASED_FIXED_PARTITION = 2, + REFERENCE_PARTITION = 3, + // Use an arbitrary partitioning scheme based on source variance within // a 64X64 SB VAR_BASED_PARTITION @@ -357,6 +348,10 @@ typedef struct { // was selected, and 2 means we use 8 tap if no 8x8 filter mode was selected. int adaptive_pred_interp_filter; + // Search through variable block partition types in non-RD mode decision + // encoding process for RTC. + int partition_check; + // Implements various heuristics to skip searching modes // The heuristics selected are based on flags // defined in the MODE_SEARCH_SKIP_HEURISTICS enum @@ -876,7 +871,7 @@ int vp9_get_preview_raw_frame(VP9_COMP *cpi, YV12_BUFFER_CONFIG *dest, int vp9_use_as_reference(VP9_COMP *cpi, int ref_frame_flags); -int vp9_update_reference(VP9_COMP *cpi, int ref_frame_flags); +void vp9_update_reference(VP9_COMP *cpi, int ref_frame_flags); int vp9_copy_reference_enc(VP9_COMP *cpi, VP9_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd); diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 0a396fff0..6c84144fb 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -26,14 +26,13 @@ #include "vp9/encoder/vp9_ratectrl.h" #include "vp9/encoder/vp9_rdopt.h" -static int full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x, +static void full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x, const TileInfo *const tile, BLOCK_SIZE bsize, int mi_row, int mi_col, int_mv *tmp_mv) { MACROBLOCKD *xd = &x->e_mbd; MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}}; - int bestsme = INT_MAX; int step_param; int sadpb = x->sadperbit16; MV mvp_full; @@ -46,9 +45,6 @@ static int full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x, int tmp_row_min = x->mv_row_min; int tmp_row_max = x->mv_row_max; - int buf_offset; - int stride = xd->plane[0].pre[0].stride; - const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi, ref); if (scaled_ref_frame) { @@ -77,7 +73,7 @@ static int full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x, for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i]; } - return INT_MAX; + return; } } @@ -129,17 +125,6 @@ static int full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x, for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i]; } - - // TODO(jingning) This step can be merged into full pixel search step in the - // re-designed log-diamond search - buf_offset = tmp_mv->as_mv.row * stride + tmp_mv->as_mv.col; - - // Find sad for current vector. - bestsme = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf, x->plane[0].src.stride, - xd->plane[0].pre[0].buf + buf_offset, - stride, 0x7fffffff); - - return bestsme; } static void sub_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x, @@ -196,7 +181,6 @@ static void model_rd_for_sb_y(VP9_COMP *cpi, BLOCK_SIZE bsize, int rate; int64_t dist; - struct macroblock_plane *const p = &x->plane[0]; struct macroblockd_plane *const pd = &xd->plane[0]; const BLOCK_SIZE bs = get_plane_block_size(bsize, pd); @@ -233,12 +217,16 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, int64_t best_rd = INT64_MAX; int64_t this_rd = INT64_MAX; - const int64_t inter_mode_thresh = 300; - const int64_t intra_mode_cost = 50; - int rate = INT_MAX; int64_t dist = INT64_MAX; + VP9_COMMON *cm = &cpi->common; + int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q); + + const int64_t inter_mode_thresh = RDCOST(x->rdmult, x->rddiv, + intra_cost_penalty, 0); + const int64_t intra_mode_cost = 50; + x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; x->skip = 0; @@ -293,9 +281,8 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, if (this_rd < (int64_t)(1 << num_pels_log2_lookup[bsize])) continue; - x->mode_sad[ref_frame][INTER_OFFSET(NEWMV)] = - full_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col, - &frame_mv[NEWMV][ref_frame]); + full_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col, + &frame_mv[NEWMV][ref_frame]); if (frame_mv[NEWMV][ref_frame].as_int == INVALID_MV) continue; @@ -345,6 +332,7 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist); rate += x->mbmode_cost[this_mode]; + rate += intra_cost_penalty; this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist); if (this_rd + intra_mode_cost < best_rd) { diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index d0037759b..2fd25ef5b 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -41,6 +41,11 @@ #include "vp9/encoder/vp9_tokenize.h" #include "vp9/encoder/vp9_variance.h" +#define RD_THRESH_MAX_FACT 64 +#define RD_THRESH_INC 1 +#define RD_THRESH_POW 1.25 +#define RD_MULT_EPB_RATIO 64 + /* Factor to weigh the rate for switchable interp filters */ #define SWITCHABLE_INTERP_RATE_FACTOR 1 @@ -2161,10 +2166,9 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, max_mv = MAX(max_mv, MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3); // only need to check zero mv once - if (!this_mv.as_int && zero_seen) { - x->mode_sad[ref_frame][i] = x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)]; + if (!this_mv.as_int && zero_seen) continue; - } + zero_seen = zero_seen || !this_mv.as_int; row_offset = this_mv.as_mv.row >> 3; @@ -2175,9 +2179,6 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride, ref_y_ptr, ref_y_stride, 0x7fffffff); - x->mode_sad[ref_frame][i] = this_sad; - if (this_mv.as_int == 0) - x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)] = this_sad; // Note if it is the best so far. if (this_sad < best_sad) { @@ -2186,12 +2187,6 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, } } - if (!zero_seen) - x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)] = - cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride, - ref_y_buffer, ref_y_stride, - 0x7fffffff); - // Note the index of the mv that worked best in the reference list. x->mv_best_ref_index[ref_frame] = best_index; x->max_mv_context[ref_frame] = max_mv; diff --git a/vp9/encoder/vp9_rdopt.h b/vp9/encoder/vp9_rdopt.h index 7d7aeedf9..6968fa604 100644 --- a/vp9/encoder/vp9_rdopt.h +++ b/vp9/encoder/vp9_rdopt.h @@ -23,11 +23,6 @@ extern "C" { (((128 + ((int64_t)R) * (RM)) >> 8) + (D << DM)) #define QIDX_SKIP_THRESH 115 -#define RD_THRESH_MAX_FACT 64 -#define RD_THRESH_INC 1 -#define RD_THRESH_POW 1.25 -#define RD_MULT_EPB_RATIO 64 - #define MV_COST_WEIGHT 108 #define MV_COST_WEIGHT_SUB 120 diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index d3097e526..2e8326099 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -963,8 +963,8 @@ static vpx_codec_err_t vp9e_update_entropy(vpx_codec_alg_priv_t *ctx, static vpx_codec_err_t vp9e_update_reference(vpx_codec_alg_priv_t *ctx, int ctr_id, va_list args) { - const int update = va_arg(args, int); - vp9_update_reference(ctx->cpi, update); + const int ref_frame_flags = va_arg(args, int); + vp9_update_reference(ctx->cpi, ref_frame_flags); return VPX_CODEC_OK; } |