char raw_hdr[32];
int is_ivf = 0;
- // TODO(tomfinegan): This can eventually go away, but for now it's required
- // because the means by which file types are detected differ in vpxdec and
- // vpxenc.
- rewind(input_ctx->file);
-
if (fread(raw_hdr, 1, 32, input_ctx->file) == 32) {
if (raw_hdr[0] == 'D' && raw_hdr[1] == 'K' &&
raw_hdr[2] == 'I' && raw_hdr[3] == 'F') {
static void write_frame_size_with_refs(VP9_COMP *cpi,
struct vp9_write_bit_buffer *wb) {
VP9_COMMON *const cm = &cpi->common;
- int refs[REFS_PER_FRAME] = {cpi->lst_fb_idx, cpi->gld_fb_idx,
- cpi->alt_fb_idx};
- int i, found = 0;
+ int found = 0;
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->ref_frame_map[refs[i]]];
+ MV_REFERENCE_FRAME ref_frame;
+ for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
+ YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, ref_frame);
found = cm->width == cfg->y_crop_width &&
cm->height == cfg->y_crop_height;
write_frame_size(cpi, wb);
} else {
- const int refs[REFS_PER_FRAME] = {cpi->lst_fb_idx, cpi->gld_fb_idx,
- cpi->alt_fb_idx};
if (!cm->show_frame)
vp9_wb_write_bit(wb, cm->intra_only);
vp9_wb_write_literal(wb, get_refresh_mask(cpi), REF_FRAMES);
write_frame_size(cpi, wb);
} else {
- int i;
+ MV_REFERENCE_FRAME ref_frame;
vp9_wb_write_literal(wb, get_refresh_mask(cpi), REF_FRAMES);
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- vp9_wb_write_literal(wb, refs[i], REF_FRAMES_LOG2);
- vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[LAST_FRAME + i]);
+ for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
+ vp9_wb_write_literal(wb, get_ref_frame_idx(cpi, ref_frame),
+ REF_FRAMES_LOG2);
+ vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[ref_frame]);
}
write_frame_size_with_refs(cpi, wb);
// Bit flag for each mode whether it has high error in comparison to others.
unsigned int modes_with_high_error;
-
- // Bit flag for each ref frame whether it has high error compared to others.
- unsigned int frames_with_high_error;
} PICK_MODE_CONTEXT;
struct macroblock_plane {
static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x,
BLOCK_SIZE bs) {
unsigned int var, sse;
- var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf,
- x->plane[0].src.stride,
+ var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
VP9_VAR_OFFS, 0, &sse);
- return (var + (1 << (num_pels_log2_lookup[bs] - 1))) >>
- num_pels_log2_lookup[bs];
+ return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}
// Original activity measure from Tim T's code.
vp9_setup_src_planes(x, cpi->Source, 0, 0);
// TODO(jkoleszar): are these initializations required?
- setup_pre_planes(xd, 0, &cm->yv12_fb[cm->ref_frame_map[cpi->lst_fb_idx]],
- 0, 0, NULL);
+ setup_pre_planes(xd, 0, get_ref_frame_buffer(cpi, LAST_FRAME), 0, 0, NULL);
setup_dst_planes(xd, get_frame_new_buffer(cm), 0, 0);
setup_block_dptrs(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
int ref;
const int is_compound = has_second_ref(mbmi);
for (ref = 0; ref < 1 + is_compound; ++ref) {
- YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->ref_frame_map[
- get_ref_frame_idx(cpi, mbmi->ref_frame[ref])]];
+ YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
+ mbmi->ref_frame[ref]);
setup_pre_planes(xd, ref, cfg, mi_row, mi_col, &xd->block_refs[ref]->sf);
}
vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
int i;
int recon_yoffset, recon_uvoffset;
- const int lst_yv12_idx = cm->ref_frame_map[cpi->lst_fb_idx];
- const int gld_yv12_idx = cm->ref_frame_map[cpi->gld_fb_idx];
- YV12_BUFFER_CONFIG *const lst_yv12 = &cm->yv12_fb[lst_yv12_idx];
- YV12_BUFFER_CONFIG *const gld_yv12 = &cm->yv12_fb[gld_yv12_idx];
+ YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
+ YV12_BUFFER_CONFIG *const gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
const int recon_y_stride = lst_yv12->y_stride;
const int recon_uv_stride = lst_yv12->uv_stride;
return fclamp(pow(error_term, power_term), 0.05, 5.0);
}
-// Given a current maxQ value sets a range for future values.
-// PGW TODO..
-// This code removes direct dependency on QIndex to determine the range
-// (now uses the actual quantizer) but has not been tuned.
-static void adjust_maxq_qrange(VP9_COMP *cpi) {
- int i;
- // Set the max corresponding to cpi->rc.avg_q * 2.0
- double q = cpi->rc.avg_q * 2.0;
- cpi->twopass.maxq_max_limit = cpi->rc.worst_quality;
- for (i = cpi->rc.best_quality; i <= cpi->rc.worst_quality; i++) {
- cpi->twopass.maxq_max_limit = i;
- if (vp9_convert_qindex_to_q(i) >= q)
- break;
- }
-
- // Set the min corresponding to cpi->rc.avg_q * 0.5
- q = cpi->rc.avg_q * 0.5;
- cpi->twopass.maxq_min_limit = cpi->rc.best_quality;
- for (i = cpi->rc.worst_quality; i >= cpi->rc.best_quality; i--) {
- cpi->twopass.maxq_min_limit = i;
- if (vp9_convert_qindex_to_q(i) <= q)
- break;
- }
-}
-
static int estimate_max_q(VP9_COMP *cpi,
FIRSTPASS_STATS *fpstats,
int section_target_bandwitdh) {
double err_correction_factor;
if (section_target_bandwitdh <= 0)
- return cpi->twopass.maxq_max_limit; // Highest value allowed
+ return cpi->rc.worst_quality; // Highest value allowed
target_norm_bits_per_mb = section_target_bandwitdh < (1 << 20)
? (512 * section_target_bandwitdh) / num_mbs
: 512 * (section_target_bandwitdh / num_mbs);
-
// Try and pick a max Q that will be high enough to encode the
// content at the given rate.
- for (q = cpi->twopass.maxq_min_limit; q < cpi->twopass.maxq_max_limit; q++) {
+ for (q = cpi->rc.best_quality; q < cpi->rc.worst_quality; q++) {
int bits_per_mb_at_this_q;
err_correction_factor = calc_correction_factor(err_per_mb,
int section_target_bandwidth =
(int)(cpi->twopass.bits_left / frames_left);
- // guess at maxq needed in 2nd pass
- cpi->twopass.maxq_max_limit = cpi->rc.worst_quality;
- cpi->twopass.maxq_min_limit = cpi->rc.best_quality;
-
tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats,
section_target_bandwidth);
void vp9_update_mbgraph_stats(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
int i, n_frames = vp9_lookahead_depth(cpi->lookahead);
- YV12_BUFFER_CONFIG *golden_ref =
- &cm->yv12_fb[cm->ref_frame_map[cpi->gld_fb_idx]];
+ YV12_BUFFER_CONFIG *golden_ref = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
// we need to look ahead beyond where the ARF transitions into
// being a GF - so exit if we don't look ahead beyond that
sf->thresh_mult_sub8x8[THR_COMP_GA] = INT_MAX;
}
+static void set_rt_speed_feature(VP9_COMMON *cm,
+ SPEED_FEATURES *sf,
+ int speed) {
+ sf->static_segmentation = 0;
+ sf->adaptive_rd_thresh = 1;
+ sf->recode_loop = (speed < 1);
+ if (speed >= 1) {
+ sf->use_square_partition_only = !frame_is_intra_only(cm);
+ sf->less_rectangular_check = 1;
+ sf->tx_size_search_method =
+ frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
+
+ if (MIN(cm->width, cm->height) >= 720)
+ sf->disable_split_mask = cm->show_frame ?
+ DISABLE_ALL_SPLIT :
+ DISABLE_ALL_INTER_SPLIT;
+ else
+ sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
+
+ sf->use_rd_breakout = 1;
+ sf->adaptive_motion_search = 1;
+ sf->adaptive_pred_filter_type = 1;
+ sf->auto_mv_step_size = 1;
+ sf->adaptive_rd_thresh = 2;
+ sf->recode_loop = 2;
+ sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
+ sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
+ sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
+ }
+ if (speed >= 2) {
+ sf->use_square_partition_only = !frame_is_intra_only(cm);
+ sf->less_rectangular_check = 1;
+ sf->tx_size_search_method =
+ frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
+
+ if (MIN(cm->width, cm->height) >= 720)
+ sf->disable_split_mask = cm->show_frame ?
+ DISABLE_ALL_SPLIT :
+ DISABLE_ALL_INTER_SPLIT;
+ else
+ sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY;
+
+ sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH
+ | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA
+ | FLAG_SKIP_INTRA_LOWVAR;
+
+ sf->use_rd_breakout = 1;
+ sf->adaptive_motion_search = 1;
+ sf->adaptive_pred_filter_type = 2;
+ sf->auto_mv_step_size = 1;
+
+ sf->disable_filter_search_var_thresh = 50;
+ sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
+
+ sf->auto_min_max_partition_size = 1;
+ sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_LOW_MOTION;
+ sf->adjust_partitioning_from_last_frame = 1;
+ sf->last_partitioning_redo_frequency = 3;
+
+ sf->adaptive_rd_thresh = 2;
+ sf->recode_loop = 2;
+ sf->use_lp32x32fdct = 1;
+ sf->mode_skip_start = 11;
+ sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
+ sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
+ sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
+ sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
+ }
+ if (speed >= 3) {
+ sf->use_square_partition_only = 1;
+ sf->tx_size_search_method = USE_LARGESTALL;
+
+ if (MIN(cm->width, cm->height) >= 720)
+ sf->disable_split_mask = DISABLE_ALL_SPLIT;
+ else
+ sf->disable_split_mask = DISABLE_ALL_INTER_SPLIT;
+
+ sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH
+ | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA
+ | FLAG_SKIP_INTRA_LOWVAR;
+
+ sf->use_rd_breakout = 1;
+ sf->adaptive_motion_search = 1;
+ sf->adaptive_pred_filter_type = 2;
+ sf->auto_mv_step_size = 1;
+
+ sf->disable_filter_search_var_thresh = 100;
+ sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
+
+ sf->auto_min_max_partition_size = 1;
+ sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_ALL;
+ sf->adjust_partitioning_from_last_frame = 1;
+ sf->last_partitioning_redo_frequency = 3;
+
+ sf->use_uv_intra_rd_estimate = 1;
+ sf->skip_encode_sb = 1;
+ sf->use_lp32x32fdct = 1;
+ sf->subpel_iters_per_step = 1;
+ sf->use_fast_coef_updates = 2;
+
+ sf->adaptive_rd_thresh = 4;
+ sf->mode_skip_start = 6;
+ }
+ if (speed >= 4) {
+ sf->use_square_partition_only = 1;
+ sf->tx_size_search_method = USE_LARGESTALL;
+ sf->disable_split_mask = DISABLE_ALL_SPLIT;
+
+ sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH
+ | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA
+ | FLAG_SKIP_COMP_REFMISMATCH | FLAG_SKIP_INTRA_LOWVAR
+ | FLAG_EARLY_TERMINATE;
+
+ sf->use_rd_breakout = 1;
+ sf->adaptive_motion_search = 1;
+ sf->adaptive_pred_filter_type = 2;
+ sf->auto_mv_step_size = 1;
+
+ sf->disable_filter_search_var_thresh = 200;
+ sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
+
+ sf->auto_min_max_partition_size = 1;
+ sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_ALL;
+ sf->adjust_partitioning_from_last_frame = 1;
+ sf->last_partitioning_redo_frequency = 3;
+
+ sf->use_uv_intra_rd_estimate = 1;
+ sf->skip_encode_sb = 1;
+ sf->use_lp32x32fdct = 1;
+ sf->subpel_iters_per_step = 1;
+ sf->use_fast_coef_updates = 2;
+
+ sf->adaptive_rd_thresh = 4;
+ sf->mode_skip_start = 6;
+
+ /* sf->intra_y_mode_mask = INTRA_DC_ONLY;
+ sf->intra_uv_mode_mask = INTRA_DC_ONLY;
+ sf->search_method = BIGDIA;
+ sf->disable_split_var_thresh = 64;
+ sf->disable_filter_search_var_thresh = 64; */
+ }
+ if (speed >= 5) {
+ int i;
+ sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
+ sf->use_one_partition_size_always = 1;
+ sf->always_this_block_size = BLOCK_16X16;
+ sf->tx_size_search_method =
+ frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
+ sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH
+ | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA
+ | FLAG_SKIP_COMP_REFMISMATCH | FLAG_SKIP_INTRA_LOWVAR
+ | FLAG_EARLY_TERMINATE;
+ sf->use_rd_breakout = 1;
+ sf->use_lp32x32fdct = 1;
+ sf->optimize_coefficients = 0;
+ sf->auto_mv_step_size = 1;
+ // sf->reduce_first_step_size = 1;
+ // sf->reference_masking = 1;
+
+ sf->disable_split_mask = DISABLE_ALL_SPLIT;
+ sf->search_method = HEX;
+ sf->subpel_iters_per_step = 1;
+ sf->disable_split_var_thresh = 64;
+ sf->disable_filter_search_var_thresh = 500;
+ for (i = 0; i < TX_SIZES; i++) {
+ sf->intra_y_mode_mask[i] = INTRA_DC_ONLY;
+ sf->intra_uv_mode_mask[i] = INTRA_DC_ONLY;
+ }
+ sf->use_fast_coef_updates = 2;
+ sf->adaptive_rd_thresh = 4;
+ sf->mode_skip_start = 6;
+ }
+}
+
void vp9_set_speed_features(VP9_COMP *cpi) {
SPEED_FEATURES *sf = &cpi->sf;
VP9_COMMON *cm = &cpi->common;
int speed = cpi->speed;
int i;
- // Only modes 0 and 1 supported for now in experimental code basae
- if (mode > 1)
- mode = 1;
+ // Convert negative speed to positive
+ if (speed < 0)
+ speed = -speed;
for (i = 0; i < MAX_MODES; ++i)
cpi->mode_chosen_counts[i] = 0;
sf->use_lp32x32fdct = 0;
sf->adaptive_motion_search = 0;
sf->adaptive_pred_filter_type = 0;
- sf->use_avoid_tested_higherror = 0;
sf->reference_masking = 0;
sf->use_one_partition_size_always = 0;
sf->less_rectangular_check = 0;
break;
case 1:
+
#if CONFIG_MULTIPLE_ARF
// Switch segmentation off.
sf->static_segmentation = 0;
#else
sf->static_segmentation = 0;
#endif
- sf->use_avoid_tested_higherror = 1;
sf->adaptive_rd_thresh = 1;
sf->recode_loop = (speed < 1);
sf->mode_skip_start = 6;
}
break;
+ case 2:
+ set_rt_speed_feature(cm, sf, speed);
+ break;
}; /* switch */
// Set rd thresholds based on mode and speed setting
LAST_FRAME_PARTITION_METHOD use_lastframe_partitioning;
TX_SIZE_SEARCH_METHOD tx_size_search_method;
int use_lp32x32fdct;
- int use_avoid_tested_higherror;
int use_one_partition_size_always;
int less_rectangular_check;
int use_square_partition_only;
double modified_error_left;
double kf_intra_err_min;
double gf_intra_err_min;
- int maxq_max_limit;
- int maxq_min_limit;
int static_scene_max_gf_interval;
int kf_bits;
// Remaining error from uncoded frames in a gf group. Two pass use only
}
}
+static YV12_BUFFER_CONFIG *get_ref_frame_buffer(VP9_COMP *cpi,
+ MV_REFERENCE_FRAME ref_frame) {
+ VP9_COMMON *const cm = &cpi->common;
+ return &cm->yv12_fb[cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)]];
+}
+
void vp9_encode_frame(VP9_COMP *cpi);
void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t *size);
/ one_percent_bits);
if (percent_low > cpi->oxcf.under_shoot_pct) {
percent_low = cpi->oxcf.under_shoot_pct;
- } else if (percent_low < 0) {
- percent_low = 0;
}
// Lower the target bandwidth for this frame.
this_frame_target -= (this_frame_target * percent_low) / 200;
/ one_percent_bits);
if (percent_high > cpi->oxcf.over_shoot_pct) {
percent_high = cpi->oxcf.over_shoot_pct;
- } else if (percent_high < 0) {
- percent_high = 0;
}
// Increase the target bandwidth for this frame.
this_frame_target += (this_frame_target * percent_high) / 200;
int i, br = 0, idx, idy;
int64_t bd = 0, block_sse = 0;
MB_PREDICTION_MODE this_mode;
+ VP9_COMMON *cm = &cpi->common;
MODE_INFO *mi = x->e_mbd.mi_8x8[0];
MB_MODE_INFO *const mbmi = &mi->mbmi;
struct macroblock_plane *const p = &x->plane[0];
i = idy * 2 + idx;
frame_mv[ZEROMV][mbmi->ref_frame[0]].as_int = 0;
- vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile,
+ vp9_append_sub8x8_mvs_for_idx(cm, &x->e_mbd, tile,
i, 0, mi_row, mi_col,
&frame_mv[NEARESTMV][mbmi->ref_frame[0]],
&frame_mv[NEARMV][mbmi->ref_frame[0]]);
if (has_second_rf) {
frame_mv[ZEROMV][mbmi->ref_frame[1]].as_int = 0;
- vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile,
+ vp9_append_sub8x8_mvs_for_idx(cm, &x->e_mbd, tile,
i, 1, mi_row, mi_col,
&frame_mv[NEARESTMV][mbmi->ref_frame[1]],
&frame_mv[NEARMV][mbmi->ref_frame[1]]);
// motion search for newmv (single predictor case only)
if (!has_second_rf && this_mode == NEWMV &&
seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) {
+ int_mv *const new_mv = &mode_mv[NEWMV];
int step_param = 0;
int further_steps;
int thissme, bestsme = INT_MAX;
else
max_mv = MAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3;
- if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) {
+ if (cpi->sf.auto_mv_step_size && cm->show_frame) {
// Take wtd average of the step_params based on the last frame's
// max mv magnitude and the best ref mvs of the current block for
// the given reference.
mvp_full.row = bsi->mvp.as_mv.row >> 3;
mvp_full.col = bsi->mvp.as_mv.col >> 3;
- if (cpi->sf.adaptive_motion_search && cpi->common.show_frame) {
+ if (cpi->sf.adaptive_motion_search && cm->show_frame) {
mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].as_mv.row >> 3;
mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].as_mv.col >> 3;
step_param = MAX(step_param, 8);
step_param,
sadpb, 1, v_fn_ptr, 1,
&bsi->ref_mv->as_mv,
- &mode_mv[NEWMV].as_mv);
+ &new_mv->as_mv);
} else if (cpi->sf.search_method == SQUARE) {
bestsme = vp9_square_search(x, &mvp_full,
step_param,
sadpb, 1, v_fn_ptr, 1,
&bsi->ref_mv->as_mv,
- &mode_mv[NEWMV].as_mv);
+ &new_mv->as_mv);
} else if (cpi->sf.search_method == BIGDIA) {
bestsme = vp9_bigdia_search(x, &mvp_full,
step_param,
sadpb, 1, v_fn_ptr, 1,
&bsi->ref_mv->as_mv,
- &mode_mv[NEWMV].as_mv);
+ &new_mv->as_mv);
} else {
bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
sadpb, further_steps, 0, v_fn_ptr,
&bsi->ref_mv->as_mv,
- &mode_mv[NEWMV]);
+ new_mv);
}
// Should we do a full search (best quality only)
if (thissme < bestsme) {
bestsme = thissme;
- mode_mv[NEWMV].as_int = mi->bmi[i].as_mv[0].as_int;
+ new_mv->as_int = mi->bmi[i].as_mv[0].as_int;
} else {
/* The full search result is actually worse so re-instate the
* previous best vector */
- mi->bmi[i].as_mv[0].as_int = mode_mv[NEWMV].as_int;
+ mi->bmi[i].as_mv[0].as_int = new_mv->as_int;
}
}
if (bestsme < INT_MAX) {
int distortion;
cpi->find_fractional_mv_step(x,
- &mode_mv[NEWMV].as_mv,
+ &new_mv->as_mv,
&bsi->ref_mv->as_mv,
- cpi->common.allow_high_precision_mv,
+ cm->allow_high_precision_mv,
x->errorperbit, v_fn_ptr,
0, cpi->sf.subpel_iters_per_step,
x->nmvjointcost, x->mvcost,
&x->pred_sse[mbmi->ref_frame[0]]);
// save motion search result for use in compound prediction
- seg_mvs[i][mbmi->ref_frame[0]].as_int = mode_mv[NEWMV].as_int;
+ seg_mvs[i][mbmi->ref_frame[0]].as_int = new_mv->as_int;
}
if (cpi->sf.adaptive_motion_search)
- x->pred_mv[mbmi->ref_frame[0]].as_int = mode_mv[NEWMV].as_int;
+ x->pred_mv[mbmi->ref_frame[0]].as_int = new_mv->as_int;
// restore src pointers
mi_buf_restore(x, orig_src, orig_pre);
int bestsme = INT_MAX;
int further_steps, step_param;
int sadpb = x->sadperbit16;
- int_mv mvp_full;
+ MV mvp_full;
int ref = mbmi->ref_frame[0];
int_mv ref_mv = mbmi->ref_mvs[ref][0];
// Adjust search parameters based on small partitions' result.
if (x->fast_ms) {
- // && abs(mvp_full.as_mv.row - x->pred_mv.as_mv.row) < 24 &&
- // abs(mvp_full.as_mv.col - x->pred_mv.as_mv.col) < 24) {
// adjust search range
step_param = 6;
if (x->fast_ms > 1)
step_param = 8;
-
- // Get prediction MV.
- mvp_full.as_int = x->pred_mv[ref].as_int;
-
- // Adjust MV sign if needed.
- if (cm->ref_frame_sign_bias[ref]) {
- mvp_full.as_mv.col *= -1;
- mvp_full.as_mv.row *= -1;
- }
} else {
// Work out the size of the first step in the mv step search.
// 0 here is maximum length first step. 1 is MAX >> 1 etc.
}
}
- mvp_full.as_int = x->mv_best_ref_index[ref] < MAX_MV_REF_CANDIDATES ?
- mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_int :
- x->pred_mv[ref].as_int;
+ mvp_full = x->mv_best_ref_index[ref] < MAX_MV_REF_CANDIDATES
+ ? mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_mv
+ : x->pred_mv[ref].as_mv;
- mvp_full.as_mv.col >>= 3;
- mvp_full.as_mv.row >>= 3;
+ mvp_full.col >>= 3;
+ mvp_full.row >>= 3;
// Further step/diamond searches as necessary
further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
if (cpi->sf.search_method == HEX) {
- bestsme = vp9_hex_search(x, &mvp_full.as_mv,
- step_param,
- sadpb, 1,
+ bestsme = vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
&cpi->fn_ptr[bsize], 1,
&ref_mv.as_mv, &tmp_mv->as_mv);
} else if (cpi->sf.search_method == SQUARE) {
- bestsme = vp9_square_search(x, &mvp_full.as_mv,
- step_param,
- sadpb, 1,
+ bestsme = vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
&cpi->fn_ptr[bsize], 1,
&ref_mv.as_mv, &tmp_mv->as_mv);
} else if (cpi->sf.search_method == BIGDIA) {
- bestsme = vp9_bigdia_search(x, &mvp_full.as_mv,
- step_param,
- sadpb, 1,
+ bestsme = vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
&cpi->fn_ptr[bsize], 1,
&ref_mv.as_mv, &tmp_mv->as_mv);
} else {
- bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full.as_mv, step_param,
+ bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
sadpb, further_steps, 1,
&cpi->fn_ptr[bsize],
&ref_mv.as_mv, tmp_mv);
mbmi->mode_context[mbmi->ref_frame[0]]);
if (!(*mode_excluded))
- *mode_excluded = is_comp_pred
- ? cpi->common.reference_mode == SINGLE_REFERENCE
- : cpi->common.reference_mode == COMPOUND_REFERENCE;
+ *mode_excluded = is_comp_pred ? cm->reference_mode == SINGLE_REFERENCE
+ : cm->reference_mode == COMPOUND_REFERENCE;
pred_exists = 0;
// Are all MVs integer pel for Y and UV
}
}
- if (cpi->common.mcomp_filter_type == SWITCHABLE)
+ if (cm->mcomp_filter_type == SWITCHABLE)
*rate2 += get_switchable_rate(x);
if (!is_comp_pred && cpi->enable_encode_breakout) {
int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
VP9_ALT_FLAG };
- int idx_list[4] = {0,
- cpi->lst_fb_idx,
- cpi->gld_fb_idx,
- cpi->alt_fb_idx};
int64_t best_rd = best_rd_so_far;
int64_t best_tx_rd[TX_MODES];
int64_t best_tx_diff[TX_MODES];
int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
MB_MODE_INFO best_mbmode = { 0 };
- int j;
int mode_index, best_mode_index = 0;
unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
vp9_prob comp_mode_p;
int64_t dist_uv[TX_SIZES];
int skip_uv[TX_SIZES];
MB_PREDICTION_MODE mode_uv[TX_SIZES];
- unsigned int ref_frame_mask = 0;
- unsigned int mode_mask = 0;
int64_t mode_distortions[MB_MODE_COUNT] = {-1};
- int64_t frame_distortions[MAX_REF_FRAMES] = {-1};
int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
const int bws = num_8x8_blocks_wide_lookup[bsize] / 2;
const int bhs = num_8x8_blocks_high_lookup[bsize] / 2;
x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
// Everywhere the flag is set the error is much higher than its neighbors.
- ctx->frames_with_high_error = 0;
ctx->modes_with_high_error = 0;
estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
*returnrate = INT_MAX;
- // Create a mask set to 1 for each reference frame used by a smaller
- // resolution.
- if (cpi->sf.use_avoid_tested_higherror) {
- switch (block_size) {
- case BLOCK_64X64:
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- ref_frame_mask |= x->mb_context[i][j].frames_with_high_error;
- mode_mask |= x->mb_context[i][j].modes_with_high_error;
- }
- }
- for (i = 0; i < 4; i++) {
- ref_frame_mask |= x->sb32_context[i].frames_with_high_error;
- mode_mask |= x->sb32_context[i].modes_with_high_error;
- }
- break;
- case BLOCK_32X32:
- for (i = 0; i < 4; i++) {
- ref_frame_mask |=
- x->mb_context[x->sb_index][i].frames_with_high_error;
- mode_mask |= x->mb_context[x->sb_index][i].modes_with_high_error;
- }
- break;
- default:
- // Until we handle all block sizes set it to present;
- ref_frame_mask = 0;
- mode_mask = 0;
- break;
- }
- ref_frame_mask = ~ref_frame_mask;
- mode_mask = ~mode_mask;
- }
-
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
x->pred_mv_sad[ref_frame] = INT_MAX;
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
- setup_buffer_inter(cpi, x, tile, idx_list[ref_frame], ref_frame,
- block_size, mi_row, mi_col,
+ setup_buffer_inter(cpi, x, tile, get_ref_frame_idx(cpi, ref_frame),
+ ref_frame, block_size, mi_row, mi_col,
frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
}
frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
if (x->fast_ms > 2 && ref_frame != x->subblock_ref)
continue;
- if (cpi->sf.use_avoid_tested_higherror && bsize >= BLOCK_8X8) {
- if (!(ref_frame_mask & (1 << ref_frame))) {
- continue;
- }
- if (!(mode_mask & (1 << this_mode))) {
- continue;
- }
- if (second_ref_frame != NONE
- && !(ref_frame_mask & (1 << second_ref_frame))) {
- continue;
- }
- }
-
mbmi->ref_frame[0] = ref_frame;
mbmi->ref_frame[1] = second_ref_frame;
|| distortion2 < mode_distortions[this_mode]) {
mode_distortions[this_mode] = distortion2;
}
- if (frame_distortions[ref_frame] == -1
- || distortion2 < frame_distortions[ref_frame]) {
- frame_distortions[ref_frame] = distortion2;
- }
// Did this mode help.. i.e. is it the new best mode
if (this_rd < best_rd || x->skip) {
}
}
- // Flag all ref frames that have a distortion thats > 2x the best we found at
- // this level.
- for (ref_frame = INTRA_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
- if (frame_distortions[ref_frame] > 2 * *returndistortion) {
- ctx->frames_with_high_error |= (1 << ref_frame);
- }
- }
-
assert((cm->mcomp_filter_type == SWITCHABLE) ||
(cm->mcomp_filter_type == best_mbmode.interp_filter) ||
!is_inter_block(&best_mbmode));
struct buf_2d yv12_mb[4][MAX_MB_PLANE];
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
VP9_ALT_FLAG };
- int idx_list[4] = {0,
- cpi->lst_fb_idx,
- cpi->gld_fb_idx,
- cpi->alt_fb_idx};
int64_t best_rd = best_rd_so_far;
int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
int64_t best_tx_rd[TX_MODES];
int64_t dist_uv[TX_SIZES];
int skip_uv[TX_SIZES];
MB_PREDICTION_MODE mode_uv[TX_SIZES] = { 0 };
- int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
- cpi->common.y_dc_delta_q);
+ int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
int_mv seg_mvs[4][MAX_REF_FRAMES];
b_mode_info best_bmodes[4];
int best_skip2 = 0;
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
- setup_buffer_inter(cpi, x, tile, idx_list[ref_frame], ref_frame,
- block_size, mi_row, mi_col,
+ setup_buffer_inter(cpi, x, tile, get_ref_frame_idx(cpi, ref_frame),
+ ref_frame, block_size, mi_row, mi_col,
frame_mv[NEARESTMV], frame_mv[NEARMV],
yv12_mb);
}
// TODO(jingning, jkoleszar): scaling reference frame not supported for
// sub8x8 blocks.
- if (ref_frame > 0 &&
- vp9_is_scaled(&cpi->common.frame_refs[ref_frame - 1].sf))
+ if (ref_frame > 0 && vp9_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
continue;
if (second_ref_frame > 0 &&
- vp9_is_scaled(&cpi->common.frame_refs[second_ref_frame - 1].sf))
+ vp9_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
continue;
set_scale_factors(cm, xd, ref_frame - 1, second_ref_frame - 1);
// Evaluate all sub-pel filters irrespective of whether we can use
// them for this frame.
mbmi->interp_filter = cm->mcomp_filter_type;
- vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
+ vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
if (comp_pred) {
if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
int newbest, rs;
int64_t rs_rd;
mbmi->interp_filter = switchable_filter_index;
- vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
+ vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile,
&mbmi->ref_mvs[ref_frame][0],
mbmi->interp_filter = (cm->mcomp_filter_type == SWITCHABLE ?
tmp_best_filter : cm->mcomp_filter_type);
- vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
+ vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
if (!pred_exists) {
// Handles the special case when a filter that is not in the
// switchable list (bilinear, 6-tap) is indicated at the frame level
if (tmp_rd == INT64_MAX)
continue;
} else {
- if (cpi->common.mcomp_filter_type == SWITCHABLE) {
+ if (cm->mcomp_filter_type == SWITCHABLE) {
int rs = get_switchable_rate(x);
tmp_best_rdu -= RDCOST(x->rdmult, x->rddiv, rs, 0);
}
rate2 += rate;
distortion2 += distortion;
- if (cpi->common.mcomp_filter_type == SWITCHABLE)
+ if (cm->mcomp_filter_type == SWITCHABLE)
rate2 += get_switchable_rate(x);
if (!mode_excluded)
- mode_excluded = comp_pred
- ? cpi->common.reference_mode == SINGLE_REFERENCE
- : cpi->common.reference_mode == COMPOUND_REFERENCE;
+ mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
+ : cm->reference_mode == COMPOUND_REFERENCE;
compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred);
}
}
- if (cpi->common.reference_mode == REFERENCE_MODE_SELECT)
+ if (cm->reference_mode == REFERENCE_MODE_SELECT)
rate2 += compmode_cost;
// Estimate the reference frame signaling cost and add it
if (!disable_skip && ref_frame != INTRA_FRAME) {
int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
- if (cpi->common.reference_mode == REFERENCE_MODE_SELECT) {
+ if (cm->reference_mode == REFERENCE_MODE_SELECT) {
single_rate = rate2 - compmode_cost;
hybrid_rate = rate2;
} else {
struct VpxInputContext input_ctx;
} AppInput;
-void usage_exit(const char *exec_name) {
+static const char *exec_name;
+
+void usage_exit() {
fprintf(stderr, "Usage: %s <options> input_filename output_filename\n",
exec_name);
fprintf(stderr, "Options:\n");
exit(EXIT_FAILURE);
}
-static int create_dummy_frame(vpx_image_t *img) {
- const size_t buf_size = img->w * img->h * 3 / 2;
- memset(img->planes[0], 129, buf_size);
- return 1;
-}
-
static void parse_command_line(int argc, const char **argv_,
AppInput *app_input, SvcContext *svc_ctx,
vpx_codec_enc_cfg_t *enc_cfg) {
die("Error: Unrecognized option %s\n", *argi);
if (argv[0] == NULL || argv[1] == 0) {
- usage_exit(argv_[0]);
+ usage_exit();
}
app_input->input_ctx.filename = argv[0];
app_input->output_filename = argv[1];
memset(&svc_ctx, 0, sizeof(svc_ctx));
svc_ctx.log_print = 1;
+ exec_name = argv[0];
parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg);
// Allocate image buffer
fclose(app_input.input_ctx.file);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
- // rewrite the output file headers with the actual frame count
+ // rewrite the output file headers with the actual frame count, and
+ // resolution of the highest layer
if (!fseek(outfile, 0, SEEK_SET)) {
+ // get resolution of highest layer
+ if (VPX_CODEC_OK != vpx_svc_get_layer_resolution(&svc_ctx,
+ svc_ctx.spatial_layers - 1,
+ &enc_cfg.g_w,
+ &enc_cfg.g_h)) {
+ die("Failed to get output resolution");
+ }
ivf_write_file_header(outfile, &enc_cfg, VP9_FOURCC, frame_cnt);
}
fclose(outfile);
text vpx_svc_set_options
text vpx_svc_set_quantizers
text vpx_svc_set_scale_factors
+text vpx_svc_get_layer_resolution
#include "third_party/libyuv/include/libyuv/scale.h"
#include "./args.h"
-#include "./ivfdec.h"
#include "./ivfenc.h"
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
return !shortread;
}
-int file_is_y4m(FILE *infile, y4m_input *y4m, const char detect[4]) {
+int file_is_y4m(const char detect[4]) {
if (memcmp(detect, "YUV4", 4) == 0) {
return 1;
}
return 0;
}
+int fourcc_is_ivf(const char detect[4]) {
+ if (memcmp(detect, "DKIF", 4) == 0) {
+ return 1;
+ }
+ return 0;
+}
/* Murmur hash derived from public domain reference implementation at
* http:// sites.google.com/site/murmurhash/
input->detect.position = 0;
if (input->detect.buf_read == 4
- && file_is_y4m(input->file, &input->y4m, input->detect.buf)) {
+ && file_is_y4m(input->detect.buf)) {
if (y4m_input_open(&input->y4m, input->file, input->detect.buf, 4,
input->only_i420) >= 0) {
input->file_type = FILE_TYPE_Y4M;
input->use_i420 = 0;
} else
fatal("Unsupported Y4M stream.");
- } else if (input->detect.buf_read == 4 && file_is_ivf(input)) {
+ } else if (input->detect.buf_read == 4 && fourcc_is_ivf(input->detect.buf)) {
fatal("IVF is not supported as input.");
} else {
input->file_type = FILE_TYPE_RAW;
return c == 'y';
}
-static void check_lag_in_frames_realtime_deadline(
- int lag_in_frames,
- int deadline,
- struct WarningList *warning_list) {
- if (deadline == VPX_DL_REALTIME && lag_in_frames != 0)
- add_warning(lag_in_frames_with_realtime, warning_list);
-}
-
static void check_quantizer(int min_q, int max_q,
struct WarningList *warning_list) {
const int lossless = min_q == 0 && max_q == 0;
void check_encoder_config(int disable_prompt,
const struct VpxEncoderConfig *global_config,
- const struct vpx_codec_enc_cfg *stream_config) {
+ struct vpx_codec_enc_cfg *stream_config) {
int num_warnings = 0;
struct WarningListNode *warning = NULL;
struct WarningList warning_list = {0};
check_quantizer(stream_config->rc_min_quantizer,
stream_config->rc_max_quantizer,
&warning_list);
- check_lag_in_frames_realtime_deadline(stream_config->g_lag_in_frames,
- global_config->deadline,
- &warning_list);
+
+ if (global_config->deadline == VPX_DL_REALTIME)
+ stream_config->g_lag_in_frames = 0;
/* Count and print warnings. */
for (warning = warning_list.warning_node;
*/
void check_encoder_config(int disable_prompt,
const struct VpxEncoderConfig *global_config,
- const struct vpx_codec_enc_cfg *stream_config);
+ struct vpx_codec_enc_cfg *stream_config);
#endif // WARNINGS_H_