diff options
Diffstat (limited to 'vp9/encoder/vp9_encodeframe.c')
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 186 |
1 files changed, 78 insertions, 108 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 5e6e77dc9..69dedaccd 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -189,10 +189,10 @@ static BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi, // Lighter version of set_offsets that only sets the mode info // pointers. -static INLINE void set_modeinfo_offsets(VP9_COMMON *const cm, - MACROBLOCKD *const xd, - int mi_row, - int mi_col) { +static INLINE void set_mode_info_offsets(VP9_COMMON *const cm, + MACROBLOCKD *const xd, + int mi_row, + int mi_col) { const int idx_str = xd->mi_stride * mi_row + mi_col; xd->mi = cm->mi + idx_str; xd->mi[0].src_mi = &xd->mi[0]; @@ -210,7 +210,7 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, set_skip_context(xd, mi_row, mi_col); - set_modeinfo_offsets(cm, xd, mi_row, mi_col); + set_mode_info_offsets(cm, xd, mi_row, mi_col); mbmi = &xd->mi[0].src_mi->mbmi; @@ -270,9 +270,8 @@ static void set_block_size(VP9_COMP * const cpi, int mi_row, int mi_col, BLOCK_SIZE bsize) { if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) { - set_modeinfo_offsets(&cpi->common, xd, mi_row, mi_col); + set_mode_info_offsets(&cpi->common, xd, mi_row, mi_col); xd->mi[0].src_mi->mbmi.sb_type = bsize; - duplicate_mode_info_in_sb(&cpi->common, xd, mi_row, mi_col, bsize); } } @@ -700,7 +699,7 @@ static void update_state(VP9_COMP *cpi, ThreadData *td, mi_addr->src_mi = mi_addr; // If segmentation in use - if (seg->enabled && output_enabled) { + if (seg->enabled) { // For in frame complexity AQ copy the segment id from the segment map. if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) { const uint8_t *const map = seg->update_map ? cpi->segmentation_map @@ -863,6 +862,18 @@ static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode, vp9_rd_cost_init(rd_cost); } +static int set_segment_rdmult(VP9_COMP *const cpi, + MACROBLOCK *const x, + int8_t segment_id) { + int segment_qindex; + VP9_COMMON *const cm = &cpi->common; + vp9_init_plane_quantizers(cpi, x); + vp9_clear_system_state(); + segment_qindex = vp9_get_qindex(&cm->seg, segment_id, + cm->base_qindex); + return vp9_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q); +} + static void rd_pick_sb_modes(VP9_COMP *cpi, TileDataEnc *tile_data, MACROBLOCK *const x, @@ -919,7 +930,6 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, if (aq_mode == VARIANCE_AQ) { const int energy = bsize <= BLOCK_16X16 ? x->mb_energy : vp9_block_energy(cpi, x, bsize); - int segment_qindex; if (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame || (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) { @@ -929,18 +939,9 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, : cm->last_frame_seg_map; mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col); } - vp9_init_plane_quantizers(cpi, x); - vp9_clear_system_state(); - segment_qindex = vp9_get_qindex(&cm->seg, mbmi->segment_id, - cm->base_qindex); - x->rdmult = vp9_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q); + x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id); } else if (aq_mode == COMPLEXITY_AQ) { - const int mi_offset = mi_row * cm->mi_cols + mi_col; - unsigned char complexity = cpi->complexity_map[mi_offset]; - const int is_edge = (mi_row <= 1) || (mi_row >= (cm->mi_rows - 2)) || - (mi_col <= 1) || (mi_col >= (cm->mi_cols - 2)); - if (!is_edge && (complexity > 128)) - x->rdmult += ((x->rdmult * (complexity - 128)) / 256); + x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id); } else if (aq_mode == CYCLIC_REFRESH_AQ) { const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map : cm->last_frame_seg_map; @@ -967,6 +968,16 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, } } + + // Examine the resulting rate and for AQ mode 2 make a segment choice. + if ((rd_cost->rate != INT_MAX) && + (aq_mode == COMPLEXITY_AQ) && (bsize >= BLOCK_16X16) && + (cm->frame_type == KEY_FRAME || + cpi->refresh_alt_ref_frame || + (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) { + vp9_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate); + } + x->rdmult = orig_rdmult; // TODO(jingning) The rate-distortion optimization flow needs to be @@ -1357,11 +1368,8 @@ static void update_state_rt(VP9_COMP *cpi, ThreadData *td, 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] = ctx->mic; xd->mi[0].src_mi = &xd->mi[0]; if (seg->enabled && cpi->oxcf.aq_mode) { @@ -1382,21 +1390,26 @@ static void update_state_rt(VP9_COMP *cpi, ThreadData *td, if (is_inter_block(mbmi)) { vp9_update_mv_count(td); - if (cm->interp_filter == SWITCHABLE) { const int pred_ctx = vp9_get_pred_context_switchable_interp(xd); ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter]; } } - 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; + if (cm->use_prev_frame_mvs) { + MV_REF *const frame_mvs = + cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; + int w, h; + + 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; + } } } @@ -1761,14 +1774,6 @@ static void rd_use_partition(VP9_COMP *cpi, if (do_recon) { int output_enabled = (bsize == BLOCK_64X64); - - // Check the projected output rate for this SB against it's target - // and and if necessary apply a Q delta using segmentation to get - // closer to the target. - if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) { - vp9_select_in_frame_q_segment(cpi, x, bsize, mi_row, mi_col, - output_enabled, chosen_rdc.rate); - } encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize, pc_tree); } @@ -2500,13 +2505,6 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td, if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX && pc_tree->index != 3) { int output_enabled = (bsize == BLOCK_64X64); - - // Check the projected output rate for this SB against it's target - // and and if necessary apply a Q delta using segmentation to get - // closer to the target. - if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) - vp9_select_in_frame_q_segment(cpi, x, bsize, mi_row, mi_col, - output_enabled, best_rdc.rate); encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize, pc_tree); } @@ -2719,27 +2717,27 @@ static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x, switch (partition) { case PARTITION_NONE: - set_modeinfo_offsets(cm, xd, mi_row, mi_col); + set_mode_info_offsets(cm, xd, mi_row, mi_col); *(xd->mi[0].src_mi) = pc_tree->none.mic; duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); break; case PARTITION_VERT: - set_modeinfo_offsets(cm, xd, mi_row, mi_col); + set_mode_info_offsets(cm, xd, mi_row, mi_col); *(xd->mi[0].src_mi) = pc_tree->vertical[0].mic; duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); if (mi_col + hbs < cm->mi_cols) { - set_modeinfo_offsets(cm, xd, mi_row, mi_col + hbs); + set_mode_info_offsets(cm, xd, mi_row, mi_col + hbs); *(xd->mi[0].src_mi) = pc_tree->vertical[1].mic; duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, bsize); } break; case PARTITION_HORZ: - set_modeinfo_offsets(cm, xd, mi_row, mi_col); + set_mode_info_offsets(cm, xd, mi_row, mi_col); *(xd->mi[0].src_mi) = pc_tree->horizontal[0].mic; duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); if (mi_row + hbs < cm->mi_rows) { - set_modeinfo_offsets(cm, xd, mi_row + hbs, mi_col); + set_mode_info_offsets(cm, xd, mi_row + hbs, mi_col); *(xd->mi[0].src_mi) = pc_tree->horizontal[1].mic; duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, bsize); } @@ -2784,7 +2782,6 @@ static void nonrd_pick_partition(VP9_COMP *cpi, ThreadData *td, int do_recon, int64_t best_rd, PC_TREE *pc_tree) { const SPEED_FEATURES *const sf = &cpi->sf; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; VP9_COMMON *const cm = &cpi->common; TileInfo *const tile_info = &tile_data->tile_info; MACROBLOCK *const x = &td->mb; @@ -3016,14 +3013,6 @@ static void nonrd_pick_partition(VP9_COMP *cpi, ThreadData *td, if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX && do_recon) { int output_enabled = (bsize == BLOCK_64X64); - - // Check the projected output rate for this SB against it's target - // and and if necessary apply a Q delta using segmentation to get - // closer to the target. - if ((oxcf->aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) { - vp9_select_in_frame_q_segment(cpi, x, bsize, mi_row, mi_col, - output_enabled, best_rdc.rate); - } encode_sb_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize, pc_tree); } @@ -3173,7 +3162,7 @@ static void nonrd_use_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, BLOCK_SIZE bsize, int output_enabled, - RD_COST *rd_cost, PC_TREE *pc_tree) { + RD_COST *dummy_cost, PC_TREE *pc_tree) { VP9_COMMON *const cm = &cpi->common; TileInfo *tile_info = &tile_data->tile_info; MACROBLOCK *const x = &td->mb; @@ -3182,9 +3171,7 @@ static void nonrd_use_partition(VP9_COMP *cpi, const int mis = cm->mi_stride; PARTITION_TYPE partition; BLOCK_SIZE subsize; - RD_COST this_rdc; - vp9_rd_cost_reset(&this_rdc); if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; @@ -3199,7 +3186,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, x, mi_row, mi_col, rd_cost, + nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_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]; @@ -3209,7 +3196,7 @@ static void nonrd_use_partition(VP9_COMP *cpi, break; case PARTITION_VERT: pc_tree->vertical[0].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost, + nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_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]; @@ -3219,23 +3206,17 @@ static void nonrd_use_partition(VP9_COMP *cpi, if (mi_col + hbs < cm->mi_cols) { pc_tree->vertical[1].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, - &this_rdc, subsize, &pc_tree->vertical[1]); + dummy_cost, 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; encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col + hbs, output_enabled, subsize, &pc_tree->vertical[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; - rd_cost->dist += this_rdc.dist; - } } break; case PARTITION_HORZ: pc_tree->horizontal[0].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost, + nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_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]; @@ -3246,48 +3227,34 @@ static void nonrd_use_partition(VP9_COMP *cpi, if (mi_row + hbs < cm->mi_rows) { pc_tree->horizontal[1].pred_pixel_ready = 1; nonrd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, - &this_rdc, subsize, &pc_tree->horizontal[0]); + dummy_cost, 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; encode_b_rt(cpi, td, tile_info, tp, mi_row + hbs, mi_col, output_enabled, subsize, &pc_tree->horizontal[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; - rd_cost->dist += this_rdc.dist; - } } break; case PARTITION_SPLIT: subsize = get_subsize(bsize, PARTITION_SPLIT); - nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, - subsize, output_enabled, rd_cost, - pc_tree->split[0]); - nonrd_use_partition(cpi, td, tile_data, mi + hbs, tp, - mi_row, mi_col + hbs, subsize, output_enabled, - &this_rdc, pc_tree->split[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; - rd_cost->dist += this_rdc.dist; - } - nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis, tp, - mi_row + hbs, mi_col, subsize, output_enabled, - &this_rdc, pc_tree->split[2]); - 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; - rd_cost->dist += this_rdc.dist; - } - nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis + hbs, tp, - mi_row + hbs, mi_col + hbs, subsize, output_enabled, - &this_rdc, pc_tree->split[3]); - 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; - rd_cost->dist += this_rdc.dist; + if (bsize == BLOCK_8X8) { + nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost, + subsize, pc_tree->leaf_split[0]); + encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, + output_enabled, subsize, pc_tree->leaf_split[0]); + } else { + nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, + subsize, output_enabled, dummy_cost, + pc_tree->split[0]); + nonrd_use_partition(cpi, td, tile_data, mi + hbs, tp, + mi_row, mi_col + hbs, subsize, output_enabled, + dummy_cost, pc_tree->split[1]); + nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis, tp, + mi_row + hbs, mi_col, subsize, output_enabled, + dummy_cost, pc_tree->split[2]); + nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis + hbs, tp, + mi_row + hbs, mi_col + hbs, subsize, output_enabled, + dummy_cost, pc_tree->split[3]); } break; default: @@ -3329,6 +3296,9 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, // Set the partition type of the 64X64 block switch (sf->partition_search_type) { case VAR_BASED_PARTITION: + // TODO(jingning) Only key frame coding supports sub8x8 block at this + // point. To be continued to enable sub8x8 block mode decision for + // P frames. choose_partitioning(cpi, tile_info, x, mi_row, mi_col); nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, BLOCK_64X64, 1, &dummy_rdc, td->pc_root); |