diff options
Diffstat (limited to 'vp9/encoder/vp9_encodeframe.c')
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 93 |
1 files changed, 80 insertions, 13 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index baa4908d4..b87a28332 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -611,6 +611,13 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi; MODE_INFO *mi_addr = &xd->mi[0]; const struct segmentation *const seg = &cm->seg; + const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type]; + const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type]; + const int x_mis = MIN(bw, cm->mi_cols - mi_col); + const int y_mis = MIN(bh, cm->mi_rows - mi_row); + MV_REF *const frame_mvs = + cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; + int w, h; const int mis = cm->mi_stride; const int mi_width = num_8x8_blocks_wide_lookup[bsize]; @@ -728,6 +735,17 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) rd_opt->filter_diff[i] += ctx->best_filter_diff[i]; } + + for (h = 0; h < y_mis; ++h) { + MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols; + for (w = 0; w < x_mis; ++w) { + MV_REF *const mv = frame_mv + w; + mv->ref_frame[0] = mi->src_mi->mbmi.ref_frame[0]; + mv->ref_frame[1] = mi->src_mi->mbmi.ref_frame[1]; + mv->mv[0].as_int = mi->src_mi->mbmi.mv[0].as_int; + mv->mv[1].as_int = mi->src_mi->mbmi.mv[1].as_int; + } + } } void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src, @@ -1293,8 +1311,16 @@ static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, VP9_COMMON *const cm = &cpi->common; MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; + MODE_INFO *const mi = xd->mi[0].src_mi; MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi; const struct segmentation *const seg = &cm->seg; + const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type]; + const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type]; + const int x_mis = MIN(bw, cm->mi_cols - mi_col); + const int y_mis = MIN(bh, cm->mi_rows - mi_row); + MV_REF *const frame_mvs = + cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; + int w, h; *(xd->mi[0].src_mi) = ctx->mic; xd->mi[0].src_mi = &xd->mi[0]; @@ -1323,6 +1349,17 @@ static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, } } + for (h = 0; h < y_mis; ++h) { + MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols; + for (w = 0; w < x_mis; ++w) { + MV_REF *const mv = frame_mv + w; + mv->ref_frame[0] = mi->src_mi->mbmi.ref_frame[0]; + mv->ref_frame[1] = mi->src_mi->mbmi.ref_frame[1]; + mv->mv[0].as_int = mi->src_mi->mbmi.mv[0].as_int; + mv->mv[1].as_int = mi->src_mi->mbmi.mv[1].as_int; + } + } + x->skip = ctx->skip; x->skip_txfm[0] = mbmi->segment_id ? 0 : ctx->skip_txfm[0]; } @@ -2673,6 +2710,22 @@ static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x, } } +// Reset the prediction pixel ready flag recursively. +static void pred_pixel_ready_reset(PC_TREE *pc_tree, BLOCK_SIZE bsize) { + pc_tree->none.pred_pixel_ready = 0; + pc_tree->horizontal[0].pred_pixel_ready = 0; + pc_tree->horizontal[1].pred_pixel_ready = 0; + pc_tree->vertical[0].pred_pixel_ready = 0; + pc_tree->vertical[1].pred_pixel_ready = 0; + + if (bsize > BLOCK_8X8) { + BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT); + int i; + for (i = 0; i < 4; ++i) + pred_pixel_ready_reset(pc_tree->split[i], subsize); + } +} + static void nonrd_pick_partition(VP9_COMP *cpi, TileDataEnc *tile_data, TOKENEXTRA **tp, int mi_row, @@ -2731,6 +2784,10 @@ static void nonrd_pick_partition(VP9_COMP *cpi, partition_vert_allowed &= force_vert_split; } + ctx->pred_pixel_ready = !(partition_vert_allowed || + partition_horz_allowed || + do_split); + // PARTITION_NONE if (partition_none_allowed) { nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, @@ -2738,7 +2795,6 @@ static void nonrd_pick_partition(VP9_COMP *cpi, ctx->mic.mbmi = xd->mi[0].src_mi->mbmi; ctx->skip_txfm[0] = x->skip_txfm[0]; ctx->skip = x->skip; - ctx->pred_pixel_ready = 0; if (this_rdc.rate != INT_MAX) { int pl = partition_plane_context(xd, mi_row, mi_col, bsize); @@ -2814,17 +2870,17 @@ static void nonrd_pick_partition(VP9_COMP *cpi, subsize = get_subsize(bsize, PARTITION_HORZ); if (sf->adaptive_motion_search) load_pred_mv(x, ctx); - + pc_tree->horizontal[0].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &sum_rdc, subsize, &pc_tree->horizontal[0]); pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0]; pc_tree->horizontal[0].skip = x->skip; - pc_tree->horizontal[0].pred_pixel_ready = 0; if (sum_rdc.rdcost < best_rdc.rdcost && mi_row + ms < cm->mi_rows) { load_pred_mv(x, ctx); + pc_tree->horizontal[1].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row + ms, mi_col, &this_rdc, subsize, &pc_tree->horizontal[1]); @@ -2832,7 +2888,6 @@ static void nonrd_pick_partition(VP9_COMP *cpi, pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0]; pc_tree->horizontal[1].skip = x->skip; - pc_tree->horizontal[1].pred_pixel_ready = 0; if (this_rdc.rate == INT_MAX) { vp9_rd_cost_reset(&sum_rdc); @@ -2849,32 +2904,32 @@ static void nonrd_pick_partition(VP9_COMP *cpi, if (sum_rdc.rdcost < best_rdc.rdcost) { best_rdc = sum_rdc; pc_tree->partitioning = PARTITION_HORZ; + } else { + pred_pixel_ready_reset(pc_tree, bsize); } } // PARTITION_VERT if (partition_vert_allowed && do_rect) { subsize = get_subsize(bsize, PARTITION_VERT); - if (sf->adaptive_motion_search) load_pred_mv(x, ctx); - + pc_tree->vertical[0].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &sum_rdc, subsize, &pc_tree->vertical[0]); pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0]; pc_tree->vertical[0].skip = x->skip; - pc_tree->vertical[0].pred_pixel_ready = 0; if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + ms < cm->mi_cols) { load_pred_mv(x, ctx); + pc_tree->vertical[1].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col + ms, &this_rdc, subsize, &pc_tree->vertical[1]); pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0]; pc_tree->vertical[1].skip = x->skip; - pc_tree->vertical[1].pred_pixel_ready = 0; if (this_rdc.rate == INT_MAX) { vp9_rd_cost_reset(&sum_rdc); @@ -2891,6 +2946,8 @@ static void nonrd_pick_partition(VP9_COMP *cpi, if (sum_rdc.rdcost < best_rdc.rdcost) { best_rdc = sum_rdc; pc_tree->partitioning = PARTITION_VERT; + } else { + pred_pixel_ready_reset(pc_tree, bsize); } } @@ -2972,27 +3029,27 @@ static void nonrd_select_partition(VP9_COMP *cpi, } else { switch (partition) { case PARTITION_NONE: + pc_tree->none.pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost, subsize, &pc_tree->none); pc_tree->none.mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->none.skip_txfm[0] = x->skip_txfm[0]; pc_tree->none.skip = x->skip; - pc_tree->none.pred_pixel_ready = 1; break; case PARTITION_VERT: + pc_tree->vertical[0].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost, subsize, &pc_tree->vertical[0]); pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0]; pc_tree->vertical[0].skip = x->skip; - pc_tree->vertical[0].pred_pixel_ready = 1; if (mi_col + hbs < cm->mi_cols) { + pc_tree->vertical[1].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col + hbs, &this_rdc, subsize, &pc_tree->vertical[1]); pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0]; pc_tree->vertical[1].skip = x->skip; - pc_tree->vertical[1].pred_pixel_ready = 1; if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX && rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) { rd_cost->rate += this_rdc.rate; @@ -3001,19 +3058,19 @@ static void nonrd_select_partition(VP9_COMP *cpi, } break; case PARTITION_HORZ: + pc_tree->horizontal[0].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost, subsize, &pc_tree->horizontal[0]); pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0]; pc_tree->horizontal[0].skip = x->skip; - pc_tree->horizontal[0].pred_pixel_ready = 1; if (mi_row + hbs < cm->mi_rows) { + pc_tree->horizontal[1].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row + hbs, mi_col, &this_rdc, subsize, &pc_tree->horizontal[0]); pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0]; pc_tree->horizontal[1].skip = x->skip; - pc_tree->horizontal[1].pred_pixel_ready = 1; if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX && rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) { rd_cost->rate += this_rdc.rate; @@ -3091,6 +3148,7 @@ static void nonrd_use_partition(VP9_COMP *cpi, switch (partition) { case PARTITION_NONE: + pc_tree->none.pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost, subsize, &pc_tree->none); pc_tree->none.mic.mbmi = xd->mi[0].src_mi->mbmi; @@ -3098,12 +3156,14 @@ static void nonrd_use_partition(VP9_COMP *cpi, pc_tree->none.skip = x->skip; break; case PARTITION_VERT: + pc_tree->vertical[0].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost, subsize, &pc_tree->vertical[0]); pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0]; pc_tree->vertical[0].skip = x->skip; if (mi_col + hbs < cm->mi_cols) { + pc_tree->vertical[1].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col + hbs, &this_rdc, subsize, &pc_tree->vertical[1]); pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi; @@ -3117,12 +3177,14 @@ static void nonrd_use_partition(VP9_COMP *cpi, } break; case PARTITION_HORZ: + pc_tree->horizontal[0].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost, subsize, &pc_tree->horizontal[0]); pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi; pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0]; pc_tree->horizontal[0].skip = x->skip; if (mi_row + hbs < cm->mi_rows) { + pc_tree->horizontal[1].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, mi_row + hbs, mi_col, &this_rdc, subsize, &pc_tree->horizontal[0]); pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi; @@ -3504,6 +3566,11 @@ static void encode_frame_internal(VP9_COMP *cpi) { vp9_initialize_me_consts(cpi, cm->base_qindex); init_encode_frame_mb_context(cpi); set_prev_mi(cm); + cm->use_prev_frame_mvs = !cm->error_resilient_mode && + cm->width == cm->last_width && + cm->height == cm->last_height && + !cm->intra_only && + cm->last_show_frame; x->quant_fp = cpi->sf.use_quant_fp; vp9_zero(x->skip_txfm); |