| Index: source/libvpx/vp9/encoder/vp9_encoder.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_encoder.c (revision 293081)
|
| +++ source/libvpx/vp9/encoder/vp9_encoder.c (working copy)
|
| @@ -134,11 +134,52 @@
|
| cpi->refresh_alt_ref_frame = 1;
|
| vp9_zero(cpi->interp_filter_selected);
|
| } else {
|
| - cm->fc = cm->frame_contexts[cm->frame_context_idx];
|
| + *cm->fc = cm->frame_contexts[cm->frame_context_idx];
|
| vp9_zero(cpi->interp_filter_selected[0]);
|
| }
|
| }
|
|
|
| +static void vp9_enc_setup_mi(VP9_COMMON *cm) {
|
| + int i;
|
| + cm->mi = cm->mip + cm->mi_stride + 1;
|
| + vpx_memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
|
| + cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
|
| + // Clear top border row
|
| + vpx_memset(cm->prev_mip, 0, sizeof(*cm->prev_mip) * cm->mi_stride);
|
| + // Clear left border column
|
| + for (i = 1; i < cm->mi_rows + 1; ++i)
|
| + vpx_memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip));
|
| +}
|
| +
|
| +static int vp9_enc_alloc_mi(VP9_COMMON *cm, int mi_size) {
|
| + cm->mip = vpx_calloc(mi_size, sizeof(*cm->mip));
|
| + if (!cm->mip)
|
| + return 1;
|
| + cm->prev_mip = vpx_calloc(mi_size, sizeof(*cm->prev_mip));
|
| + if (!cm->prev_mip)
|
| + return 1;
|
| + cm->mi_alloc_size = mi_size;
|
| + return 0;
|
| +}
|
| +
|
| +static void vp9_enc_free_mi(VP9_COMMON *cm) {
|
| + vpx_free(cm->mip);
|
| + cm->mip = NULL;
|
| + vpx_free(cm->prev_mip);
|
| + cm->prev_mip = NULL;
|
| +}
|
| +
|
| +static void vp9_swap_mi_and_prev_mi(VP9_COMMON *cm) {
|
| + // Current mip will be the prev_mip for the next frame.
|
| + MODE_INFO *temp = cm->prev_mip;
|
| + cm->prev_mip = cm->mip;
|
| + cm->mip = temp;
|
| +
|
| + // Update the upper left visible macroblock ptrs.
|
| + cm->mi = cm->mip + cm->mi_stride + 1;
|
| + cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
|
| +}
|
| +
|
| void vp9_initialize_enc() {
|
| static int init_done = 0;
|
|
|
| @@ -160,6 +201,9 @@
|
| VP9_COMMON *const cm = &cpi->common;
|
| int i;
|
|
|
| + vpx_free(cpi->tile_data);
|
| + cpi->tile_data = NULL;
|
| +
|
| // Delete sementation map
|
| vpx_free(cpi->segmentation_map);
|
| cpi->segmentation_map = NULL;
|
| @@ -191,6 +235,9 @@
|
| cpi->nmvsadcosts_hp[0] = NULL;
|
| cpi->nmvsadcosts_hp[1] = NULL;
|
|
|
| + vpx_free(cpi->frame_counts);
|
| + cpi->frame_counts = NULL;
|
| +
|
| vp9_cyclic_refresh_free(cpi->cyclic_refresh);
|
| cpi->cyclic_refresh = NULL;
|
|
|
| @@ -257,7 +304,7 @@
|
| vp9_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
|
| vp9_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
|
|
|
| - cc->fc = cm->fc;
|
| + cc->fc = *cm->fc;
|
| }
|
|
|
| static void restore_coding_context(VP9_COMP *cpi) {
|
| @@ -286,7 +333,7 @@
|
| vp9_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
|
| vp9_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
|
|
|
| - cm->fc = cc->fc;
|
| + *cm->fc = cc->fc;
|
| }
|
|
|
| static void configure_static_seg_features(VP9_COMP *cpi) {
|
| @@ -577,7 +624,7 @@
|
| if ((cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) ||
|
| ((cpi->svc.number_temporal_layers > 1 ||
|
| cpi->svc.number_spatial_layers > 1) &&
|
| - cpi->oxcf.pass == 2)) {
|
| + cpi->oxcf.pass != 1)) {
|
| vp9_init_layer_context(cpi);
|
| }
|
|
|
| @@ -1278,7 +1325,7 @@
|
| cpi->oxcf.rc_mode == VPX_CBR) ||
|
| ((cpi->svc.number_temporal_layers > 1 ||
|
| cpi->svc.number_spatial_layers > 1) &&
|
| - cpi->oxcf.pass == 2)) {
|
| + cpi->oxcf.pass != 1)) {
|
| vp9_update_layer_context_change_config(cpi,
|
| (int)cpi->oxcf.target_bandwidth);
|
| }
|
| @@ -1357,7 +1404,7 @@
|
|
|
|
|
| VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
|
| - unsigned int i, j;
|
| + unsigned int i;
|
| VP9_COMP *const cpi = vpx_memalign(32, sizeof(VP9_COMP));
|
| VP9_COMMON *const cm = cpi != NULL ? &cpi->common : NULL;
|
|
|
| @@ -1373,7 +1420,16 @@
|
| }
|
|
|
| cm->error.setjmp = 1;
|
| + cm->alloc_mi = vp9_enc_alloc_mi;
|
| + cm->free_mi = vp9_enc_free_mi;
|
| + cm->setup_mi = vp9_enc_setup_mi;
|
|
|
| + CHECK_MEM_ERROR(cm, cm->fc,
|
| + (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc)));
|
| + CHECK_MEM_ERROR(cm, cm->frame_contexts,
|
| + (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS,
|
| + sizeof(*cm->frame_contexts)));
|
| +
|
| cpi->use_svc = 0;
|
|
|
| init_config(cpi, oxcf);
|
| @@ -1381,6 +1437,7 @@
|
|
|
| cm->current_video_frame = 0;
|
| cpi->partition_search_skippable_frame = 0;
|
| + cpi->tile_data = NULL;
|
|
|
| // Create the encoder segmentation map and set all entries to 0
|
| CHECK_MEM_ERROR(cm, cpi->segmentation_map,
|
| @@ -1416,6 +1473,9 @@
|
| CHECK_MEM_ERROR(cm, cpi->nmvsadcosts_hp[1],
|
| vpx_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts_hp[1])));
|
|
|
| + CHECK_MEM_ERROR(cm, cpi->frame_counts, vpx_calloc(1,
|
| + sizeof(*cpi->frame_counts)));
|
| +
|
| for (i = 0; i < (sizeof(cpi->mbgraph_stats) /
|
| sizeof(cpi->mbgraph_stats[0])); i++) {
|
| CHECK_MEM_ERROR(cm, cpi->mbgraph_stats[i].mb_stats,
|
| @@ -1435,25 +1495,7 @@
|
| #endif
|
|
|
| cpi->refresh_alt_ref_frame = 0;
|
| -
|
| - // Note that at the moment multi_arf will not work with svc.
|
| - // For the current check in all the execution paths are defaulted to 0
|
| - // pending further tuning and testing. The code is left in place here
|
| - // as a place holder in regard to the required paths.
|
| cpi->multi_arf_last_grp_enabled = 0;
|
| - if (oxcf->pass == 2) {
|
| - if (cpi->use_svc) {
|
| - cpi->multi_arf_allowed = 0;
|
| - cpi->multi_arf_enabled = 0;
|
| - } else {
|
| - // Disable by default for now.
|
| - cpi->multi_arf_allowed = 0;
|
| - cpi->multi_arf_enabled = 0;
|
| - }
|
| - } else {
|
| - cpi->multi_arf_allowed = 0;
|
| - cpi->multi_arf_enabled = 0;
|
| - }
|
|
|
| cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
|
| #if CONFIG_INTERNAL_STATS
|
| @@ -1589,7 +1631,8 @@
|
| }
|
| }
|
|
|
| - vp9_set_speed_features(cpi);
|
| + vp9_set_speed_features_framesize_independent(cpi);
|
| + vp9_set_speed_features_framesize_dependent(cpi);
|
|
|
| // Allocate memory to store variances for a frame.
|
| CHECK_MEM_ERROR(cm, cpi->source_diff_var,
|
| @@ -1597,14 +1640,6 @@
|
| cpi->source_var_thresh = 0;
|
| cpi->frames_till_next_var_check = 0;
|
|
|
| - // Default rd threshold factors for mode selection
|
| - for (i = 0; i < BLOCK_SIZES; ++i) {
|
| - for (j = 0; j < MAX_MODES; ++j) {
|
| - cpi->rd.thresh_freq_fact[i][j] = 32;
|
| - cpi->rd.mode_map[i][j] = j;
|
| - }
|
| - }
|
| -
|
| #define BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF)\
|
| cpi->fn_ptr[BT].sdf = SDF; \
|
| cpi->fn_ptr[BT].sdaf = SDAF; \
|
| @@ -1693,12 +1728,13 @@
|
| }
|
|
|
| void vp9_remove_compressor(VP9_COMP *cpi) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| unsigned int i;
|
|
|
| if (!cpi)
|
| return;
|
|
|
| - if (cpi && (cpi->common.current_video_frame > 0)) {
|
| + if (cpi && (cm->current_video_frame > 0)) {
|
| #if CONFIG_INTERNAL_STATS
|
|
|
| vp9_clear_system_state();
|
| @@ -1781,7 +1817,7 @@
|
| }
|
| #endif
|
|
|
| - vp9_remove_common(&cpi->common);
|
| + vp9_remove_common(cm);
|
| vpx_free(cpi);
|
|
|
| #if CONFIG_VP9_TEMPORAL_DENOISING
|
| @@ -2272,7 +2308,6 @@
|
| static int recode_loop_test(const VP9_COMP *cpi,
|
| int high_limit, int low_limit,
|
| int q, int maxq, int minq) {
|
| - const VP9_COMMON *const cm = &cpi->common;
|
| const RATE_CONTROL *const rc = &cpi->rc;
|
| const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
| int force_recode = 0;
|
| @@ -2286,8 +2321,7 @@
|
| // and the frame is a key frame, golden frame or alt_ref_frame
|
| } else if ((cpi->sf.recode_loop == ALLOW_RECODE) ||
|
| ((cpi->sf.recode_loop == ALLOW_RECODE_KFARFGF) &&
|
| - (cm->frame_type == KEY_FRAME ||
|
| - cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) {
|
| + frame_is_kf_gf_arf(cpi))) {
|
| // General over and under shoot tests
|
| if ((rc->projected_frame_size > high_limit && q < maxq) ||
|
| (rc->projected_frame_size < low_limit && q > minq)) {
|
| @@ -2416,30 +2450,47 @@
|
| const VP9_REFFRAME ref_mask[3] = {VP9_LAST_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG};
|
|
|
| for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
| - const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
|
| - const YV12_BUFFER_CONFIG *const ref = &cm->frame_bufs[idx].buf;
|
| + // Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1).
|
| + if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) {
|
| + const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
|
| + const YV12_BUFFER_CONFIG *const ref = &cm->frame_bufs[idx].buf;
|
|
|
| - // Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1).
|
| - if ((cpi->ref_frame_flags & ref_mask[ref_frame - 1]) &&
|
| - (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height)) {
|
| - const int new_fb = get_free_fb(cm);
|
| - vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
|
| - cm->width, cm->height,
|
| - cm->subsampling_x, cm->subsampling_y,
|
| #if CONFIG_VP9_HIGHBITDEPTH
|
| - cm->use_highbitdepth,
|
| -#endif // CONFIG_VP9_HIGHBITDEPTH
|
| - VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
| -#if CONFIG_VP9_HIGHBITDEPTH
|
| - scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf,
|
| - (int)cm->bit_depth);
|
| + if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
|
| + const int new_fb = get_free_fb(cm);
|
| + cm->cur_frame = &cm->frame_bufs[new_fb];
|
| + vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
|
| + cm->width, cm->height,
|
| + cm->subsampling_x, cm->subsampling_y,
|
| + cm->use_highbitdepth,
|
| + VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
| + scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf,
|
| + (int)cm->bit_depth);
|
| #else
|
| - scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf);
|
| + if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
|
| + const int new_fb = get_free_fb(cm);
|
| + vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
|
| + cm->width, cm->height,
|
| + cm->subsampling_x, cm->subsampling_y,
|
| + VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
| + scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf);
|
| #endif // CONFIG_VP9_HIGHBITDEPTH
|
| - cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
|
| + cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
|
| + if (cm->frame_bufs[new_fb].mvs == NULL ||
|
| + cm->frame_bufs[new_fb].mi_rows < cm->mi_rows ||
|
| + cm->frame_bufs[new_fb].mi_cols < cm->mi_cols) {
|
| + cm->frame_bufs[new_fb].mvs =
|
| + (MV_REF *)vpx_calloc(cm->mi_rows * cm->mi_cols,
|
| + sizeof(*cm->frame_bufs[new_fb].mvs));
|
| + cm->frame_bufs[new_fb].mi_rows = cm->mi_rows;
|
| + cm->frame_bufs[new_fb].mi_cols = cm->mi_cols;
|
| + }
|
| + } else {
|
| + cpi->scaled_ref_idx[ref_frame - 1] = idx;
|
| + ++cm->frame_bufs[idx].ref_count;
|
| + }
|
| } else {
|
| - cpi->scaled_ref_idx[ref_frame - 1] = idx;
|
| - cm->frame_bufs[idx].ref_count++;
|
| + cpi->scaled_ref_idx[ref_frame - 1] = INVALID_REF_BUFFER_IDX;
|
| }
|
| }
|
| }
|
| @@ -2447,9 +2498,15 @@
|
| static void release_scaled_references(VP9_COMP *cpi) {
|
| VP9_COMMON *cm = &cpi->common;
|
| int i;
|
| -
|
| - for (i = 0; i < 3; i++)
|
| - cm->frame_bufs[cpi->scaled_ref_idx[i]].ref_count--;
|
| + for (i = 0; i < MAX_REF_FRAMES; ++i) {
|
| + const int idx = cpi->scaled_ref_idx[i];
|
| + RefCntBuffer *const buf =
|
| + idx != INVALID_REF_BUFFER_IDX ? &cm->frame_bufs[idx] : NULL;
|
| + if (buf != NULL) {
|
| + --buf->ref_count;
|
| + cpi->scaled_ref_idx[i] = INVALID_REF_BUFFER_IDX;
|
| + }
|
| + }
|
| }
|
|
|
| static void full_to_model_count(unsigned int *model_count,
|
| @@ -2534,10 +2591,176 @@
|
| }
|
| #endif
|
|
|
| -static void encode_without_recode_loop(VP9_COMP *cpi,
|
| - int q) {
|
| +static void set_mv_search_params(VP9_COMP *cpi) {
|
| + const VP9_COMMON *const cm = &cpi->common;
|
| + const unsigned int max_mv_def = MIN(cm->width, cm->height);
|
| +
|
| + // Default based on max resolution.
|
| + cpi->mv_step_param = vp9_init_search_range(max_mv_def);
|
| +
|
| + if (cpi->sf.mv.auto_mv_step_size) {
|
| + if (frame_is_intra_only(cm)) {
|
| + // Initialize max_mv_magnitude for use in the first INTER frame
|
| + // after a key/intra-only frame.
|
| + cpi->max_mv_magnitude = max_mv_def;
|
| + } else {
|
| + if (cm->show_frame) {
|
| + // Allow mv_steps to correspond to twice the max mv magnitude found
|
| + // in the previous frame, capped by the default max_mv_magnitude based
|
| + // on resolution.
|
| + cpi->mv_step_param =
|
| + vp9_init_search_range(MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
|
| + }
|
| + cpi->max_mv_magnitude = 0;
|
| + }
|
| + }
|
| +}
|
| +
|
| +static void set_size_independent_vars(VP9_COMP *cpi) {
|
| + vp9_set_speed_features_framesize_independent(cpi);
|
| + vp9_set_rd_speed_thresholds(cpi);
|
| + vp9_set_rd_speed_thresholds_sub8x8(cpi);
|
| + cpi->common.interp_filter = cpi->sf.default_interp_filter;
|
| +}
|
| +
|
| +static void set_size_dependent_vars(VP9_COMP *cpi, int *q,
|
| + int *bottom_index, int *top_index) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| + const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
| +
|
| + // Setup variables that depend on the dimensions of the frame.
|
| + vp9_set_speed_features_framesize_dependent(cpi);
|
| +
|
| + // Decide q and q bounds.
|
| + *q = vp9_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
|
| +
|
| + if (!frame_is_intra_only(cm)) {
|
| + vp9_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
|
| + }
|
| +
|
| + // Configure experimental use of segmentation for enhanced coding of
|
| + // static regions if indicated.
|
| + // Only allowed in the second pass of a two pass encode, as it requires
|
| + // lagged coding, and if the relevant speed feature flag is set.
|
| + if (oxcf->pass == 2 && cpi->sf.static_segmentation)
|
| + configure_static_seg_features(cpi);
|
| +
|
| +#if CONFIG_VP9_POSTPROC
|
| + if (oxcf->noise_sensitivity > 0) {
|
| + int l = 0;
|
| + switch (oxcf->noise_sensitivity) {
|
| + case 1:
|
| + l = 20;
|
| + break;
|
| + case 2:
|
| + l = 40;
|
| + break;
|
| + case 3:
|
| + l = 60;
|
| + break;
|
| + case 4:
|
| + case 5:
|
| + l = 100;
|
| + break;
|
| + case 6:
|
| + l = 150;
|
| + break;
|
| + }
|
| + vp9_denoise(cpi->Source, cpi->Source, l);
|
| + }
|
| +#endif // CONFIG_VP9_POSTPROC
|
| +}
|
| +
|
| +static void init_motion_estimation(VP9_COMP *cpi) {
|
| + int y_stride = cpi->scaled_source.y_stride;
|
| +
|
| + if (cpi->sf.mv.search_method == NSTEP) {
|
| + vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
|
| + } else if (cpi->sf.mv.search_method == DIAMOND) {
|
| + vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
|
| + }
|
| +}
|
| +
|
| +void set_frame_size(VP9_COMP *cpi) {
|
| + int ref_frame;
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
| + MACROBLOCKD *const xd = &cpi->mb.e_mbd;
|
| +
|
| + if (oxcf->pass == 2 &&
|
| + cm->current_video_frame == 0 &&
|
| + oxcf->resize_mode == RESIZE_FIXED &&
|
| + oxcf->rc_mode == VPX_VBR) {
|
| + // Internal scaling is triggered on the first frame.
|
| + vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
|
| + oxcf->scaled_frame_height);
|
| + }
|
| +
|
| + if ((oxcf->pass == 2) &&
|
| + (!cpi->use_svc ||
|
| + (is_two_pass_svc(cpi) &&
|
| + cpi->svc.encode_empty_frame_state != ENCODING))) {
|
| + vp9_set_target_rate(cpi);
|
| + }
|
| +
|
| + // Reset the frame pointers to the current frame size.
|
| + vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
|
| + cm->width, cm->height,
|
| + cm->subsampling_x, cm->subsampling_y,
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + cm->use_highbitdepth,
|
| +#endif
|
| + VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
| +
|
| + alloc_util_frame_buffers(cpi);
|
| + init_motion_estimation(cpi);
|
| +
|
| + for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
| + const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
|
| + YV12_BUFFER_CONFIG *const buf = &cm->frame_bufs[idx].buf;
|
| + RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1];
|
| + ref_buf->buf = buf;
|
| + ref_buf->idx = idx;
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + vp9_setup_scale_factors_for_frame(&ref_buf->sf,
|
| + buf->y_crop_width, buf->y_crop_height,
|
| + cm->width, cm->height,
|
| + (buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
|
| + 1 : 0);
|
| +#else
|
| + vp9_setup_scale_factors_for_frame(&ref_buf->sf,
|
| + buf->y_crop_width, buf->y_crop_height,
|
| + cm->width, cm->height);
|
| +#endif // CONFIG_VP9_HIGHBITDEPTH
|
| + if (vp9_is_scaled(&ref_buf->sf))
|
| + vp9_extend_frame_borders(buf);
|
| + }
|
| +
|
| + set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
|
| +}
|
| +
|
| +static void encode_without_recode_loop(VP9_COMP *cpi) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + int q, bottom_index, top_index; // Dummy variables.
|
| +
|
| vp9_clear_system_state();
|
| +
|
| + set_frame_size(cpi);
|
| +
|
| + cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
|
| + &cpi->scaled_source);
|
| +
|
| + if (cpi->unscaled_last_source != NULL)
|
| + cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
|
| + &cpi->scaled_last_source);
|
| +
|
| + if (frame_is_intra_only(cm) == 0) {
|
| + vp9_scale_references(cpi);
|
| + }
|
| +
|
| + set_size_independent_vars(cpi);
|
| + set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
|
| +
|
| vp9_set_quantizer(cm, q);
|
| setup_frame(cpi);
|
| // Variance adaptive and in frame q adjustment experiments are mutually
|
| @@ -2560,28 +2783,54 @@
|
|
|
| static void encode_with_recode_loop(VP9_COMP *cpi,
|
| size_t *size,
|
| - uint8_t *dest,
|
| - int q,
|
| - int bottom_index,
|
| - int top_index) {
|
| + uint8_t *dest) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| + int bottom_index, top_index;
|
| int loop_count = 0;
|
| int loop = 0;
|
| int overshoot_seen = 0;
|
| int undershoot_seen = 0;
|
| - int q_low = bottom_index, q_high = top_index;
|
| int frame_over_shoot_limit;
|
| int frame_under_shoot_limit;
|
| + int q = 0, q_low = 0, q_high = 0;
|
| + int frame_size_changed = 0;
|
|
|
| - // Decide frame size bounds
|
| - vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
|
| - &frame_under_shoot_limit,
|
| - &frame_over_shoot_limit);
|
| + set_size_independent_vars(cpi);
|
|
|
| do {
|
| vp9_clear_system_state();
|
|
|
| + set_frame_size(cpi);
|
| +
|
| + if (loop_count == 0 || frame_size_changed != 0) {
|
| + set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
|
| + q_low = bottom_index;
|
| + q_high = top_index;
|
| +
|
| + // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
|
| + set_mv_search_params(cpi);
|
| + }
|
| +
|
| + // Decide frame size bounds
|
| + vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
|
| + &frame_under_shoot_limit,
|
| + &frame_over_shoot_limit);
|
| +
|
| + cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
|
| + &cpi->scaled_source);
|
| +
|
| + if (cpi->unscaled_last_source != NULL)
|
| + cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
|
| + &cpi->scaled_last_source);
|
| +
|
| + if (frame_is_intra_only(cm) == 0) {
|
| + if (loop_count > 0) {
|
| + release_scaled_references(cpi);
|
| + }
|
| + vp9_scale_references(cpi);
|
| + }
|
| +
|
| vp9_set_quantizer(cm, q);
|
|
|
| if (loop_count == 0)
|
| @@ -2778,7 +3027,9 @@
|
| if (gold_is_last)
|
| flags &= ~VP9_GOLD_FLAG;
|
|
|
| - if (cpi->rc.frames_till_gf_update_due == INT_MAX && !is_two_pass_svc(cpi))
|
| + if (cpi->rc.frames_till_gf_update_due == INT_MAX &&
|
| + (cpi->svc.number_temporal_layers == 1 &&
|
| + cpi->svc.number_spatial_layers == 1))
|
| flags &= ~VP9_GOLD_FLAG;
|
|
|
| if (alt_is_last)
|
| @@ -2823,25 +3074,6 @@
|
| }
|
| }
|
|
|
| -static int is_skippable_frame(const VP9_COMP *cpi) {
|
| - // If the current frame does not have non-zero motion vector detected in the
|
| - // first pass, and so do its previous and forward frames, then this frame
|
| - // can be skipped for partition check, and the partition size is assigned
|
| - // according to the variance
|
| - const SVC *const svc = &cpi->svc;
|
| - const TWO_PASS *const twopass = is_two_pass_svc(cpi) ?
|
| - &svc->layer_context[svc->spatial_layer_id].twopass : &cpi->twopass;
|
| -
|
| - return (!frame_is_intra_only(&cpi->common) &&
|
| - twopass->stats_in - 2 > twopass->stats_in_start &&
|
| - twopass->stats_in < twopass->stats_in_end &&
|
| - (twopass->stats_in - 1)->pcnt_inter - (twopass->stats_in - 1)->pcnt_motion
|
| - == 1 &&
|
| - (twopass->stats_in - 2)->pcnt_inter - (twopass->stats_in - 2)->pcnt_motion
|
| - == 1 &&
|
| - twopass->stats_in->pcnt_inter - twopass->stats_in->pcnt_motion == 1);
|
| -}
|
| -
|
| static void set_arf_sign_bias(VP9_COMP *cpi) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| int arf_sign_bias;
|
| @@ -2858,31 +3090,6 @@
|
| cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
|
| }
|
|
|
| -static void set_mv_search_params(VP9_COMP *cpi) {
|
| - const VP9_COMMON *const cm = &cpi->common;
|
| - const unsigned int max_mv_def = MIN(cm->width, cm->height);
|
| -
|
| - // Default based on max resolution.
|
| - cpi->mv_step_param = vp9_init_search_range(max_mv_def);
|
| -
|
| - if (cpi->sf.mv.auto_mv_step_size) {
|
| - if (frame_is_intra_only(cm)) {
|
| - // Initialize max_mv_magnitude for use in the first INTER frame
|
| - // after a key/intra-only frame.
|
| - cpi->max_mv_magnitude = max_mv_def;
|
| - } else {
|
| - if (cm->show_frame)
|
| - // Allow mv_steps to correspond to twice the max mv magnitude found
|
| - // in the previous frame, capped by the default max_mv_magnitude based
|
| - // on resolution.
|
| - cpi->mv_step_param =
|
| - vp9_init_search_range(MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
|
| - cpi->max_mv_magnitude = 0;
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| int setup_interp_filter_search_mask(VP9_COMP *cpi) {
|
| INTERP_FILTER ifilter;
|
| int ref_total[MAX_REF_FRAMES] = {0};
|
| @@ -2917,21 +3124,9 @@
|
| const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
| struct segmentation *const seg = &cm->seg;
|
| TX_SIZE t;
|
| - int q;
|
| - int top_index;
|
| - int bottom_index;
|
|
|
| set_ext_overrides(cpi);
|
|
|
| - cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
|
| - &cpi->scaled_source);
|
| -
|
| - if (cpi->unscaled_last_source != NULL)
|
| - cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
|
| - &cpi->scaled_last_source);
|
| -
|
| - vp9_scale_references(cpi);
|
| -
|
| vp9_clear_system_state();
|
|
|
| // Enable or disable mode based tweaking of the zbin.
|
| @@ -2946,14 +3141,11 @@
|
| // Set default state for segment based loop filter update flags.
|
| cm->lf.mode_ref_delta_update = 0;
|
|
|
| - set_mv_search_params(cpi);
|
| -
|
| if (cpi->oxcf.pass == 2 &&
|
| cpi->sf.adaptive_interp_filter_search)
|
| cpi->sf.interp_filter_search_mask =
|
| setup_interp_filter_search_mask(cpi);
|
|
|
| -
|
| // Set various flags etc to special state if it is a key frame.
|
| if (frame_is_intra_only(cm)) {
|
| // Reset the loop filter deltas and segmentation map.
|
| @@ -3013,20 +3205,6 @@
|
| }
|
| }
|
|
|
| - // Configure experimental use of segmentation for enhanced coding of
|
| - // static regions if indicated.
|
| - // Only allowed in second pass of two pass (as requires lagged coding)
|
| - // and if the relevant speed feature flag is set.
|
| - if (oxcf->pass == 2 && cpi->sf.static_segmentation)
|
| - configure_static_seg_features(cpi);
|
| -
|
| - // Check if the current frame is skippable for the partition search in the
|
| - // second pass according to the first pass stats
|
| - if (cpi->sf.allow_partition_search_skip && oxcf->pass == 2 &&
|
| - (!cpi->use_svc || is_two_pass_svc(cpi))) {
|
| - cpi->partition_search_skippable_frame = is_skippable_frame(cpi);
|
| - }
|
| -
|
| // For 1 pass CBR, check if we are dropping this frame.
|
| // Never drop on key frame.
|
| if (oxcf->pass == 0 &&
|
| @@ -3041,31 +3219,6 @@
|
|
|
| vp9_clear_system_state();
|
|
|
| -#if CONFIG_VP9_POSTPROC
|
| - if (oxcf->noise_sensitivity > 0) {
|
| - int l = 0;
|
| - switch (oxcf->noise_sensitivity) {
|
| - case 1:
|
| - l = 20;
|
| - break;
|
| - case 2:
|
| - l = 40;
|
| - break;
|
| - case 3:
|
| - l = 60;
|
| - break;
|
| - case 4:
|
| - case 5:
|
| - l = 100;
|
| - break;
|
| - case 6:
|
| - l = 150;
|
| - break;
|
| - }
|
| - vp9_denoise(cpi->Source, cpi->Source, l);
|
| - }
|
| -#endif
|
| -
|
| #if CONFIG_INTERNAL_STATS
|
| {
|
| int i;
|
| @@ -3074,24 +3227,10 @@
|
| }
|
| #endif
|
|
|
| - vp9_set_speed_features(cpi);
|
| -
|
| - vp9_set_rd_speed_thresholds(cpi);
|
| - vp9_set_rd_speed_thresholds_sub8x8(cpi);
|
| -
|
| - // Decide q and q bounds.
|
| - q = vp9_rc_pick_q_and_bounds(cpi, &bottom_index, &top_index);
|
| -
|
| - if (!frame_is_intra_only(cm)) {
|
| - cm->interp_filter = cpi->sf.default_interp_filter;
|
| - /* TODO: Decide this more intelligently */
|
| - vp9_set_high_precision_mv(cpi, q < HIGH_PRECISION_MV_QTHRESH);
|
| - }
|
| -
|
| if (cpi->sf.recode_loop == DISALLOW_RECODE) {
|
| - encode_without_recode_loop(cpi, q);
|
| + encode_without_recode_loop(cpi);
|
| } else {
|
| - encode_with_recode_loop(cpi, size, dest, q, bottom_index, top_index);
|
| + encode_with_recode_loop(cpi, size, dest);
|
| }
|
|
|
| #if CONFIG_VP9_TEMPORAL_DENOISING
|
| @@ -3136,11 +3275,13 @@
|
| if (cm->seg.update_map)
|
| update_reference_segmentation_map(cpi);
|
|
|
| - release_scaled_references(cpi);
|
| + if (frame_is_intra_only(cm) == 0) {
|
| + release_scaled_references(cpi);
|
| + }
|
| vp9_update_reference_frames(cpi);
|
|
|
| for (t = TX_4X4; t <= TX_32X32; t++)
|
| - full_to_model_counts(cm->counts.coef[t], cpi->coef_counts[t]);
|
| + full_to_model_counts(cm->counts.coef[t], cpi->frame_counts->coef_counts[t]);
|
|
|
| if (!cm->error_resilient_mode && !cm->frame_parallel_decoding_mode)
|
| vp9_adapt_coef_probs(cm);
|
| @@ -3196,7 +3337,6 @@
|
|
|
| if (cm->show_frame) {
|
| vp9_swap_mi_and_prev_mi(cm);
|
| -
|
| // Don't increment frame counters if this was an altref buffer
|
| // update not a real frame
|
| ++cm->current_video_frame;
|
| @@ -3203,6 +3343,7 @@
|
| if (cpi->use_svc)
|
| vp9_inc_frame_in_layer(cpi);
|
| }
|
| + cm->prev_frame = cm->cur_frame;
|
|
|
| if (is_two_pass_svc(cpi))
|
| cpi->svc.layer_context[cpi->svc.spatial_layer_id].last_frame_type =
|
| @@ -3234,16 +3375,6 @@
|
| vp9_twopass_postencode_update(cpi);
|
| }
|
|
|
| -static void init_motion_estimation(VP9_COMP *cpi) {
|
| - int y_stride = cpi->scaled_source.y_stride;
|
| -
|
| - if (cpi->sf.mv.search_method == NSTEP) {
|
| - vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
|
| - } else if (cpi->sf.mv.search_method == DIAMOND) {
|
| - vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
|
| - }
|
| -}
|
| -
|
| static void check_initial_width(VP9_COMP *cpi,
|
| #if CONFIG_VP9_HIGHBITDEPTH
|
| int use_highbitdepth,
|
| @@ -3262,10 +3393,11 @@
|
| alloc_ref_frame_buffers(cpi);
|
| alloc_util_frame_buffers(cpi);
|
|
|
| - init_motion_estimation(cpi);
|
| + init_motion_estimation(cpi); // TODO(agrange) This can be removed.
|
|
|
| cpi->initial_width = cm->width;
|
| cpi->initial_height = cm->height;
|
| + cpi->initial_mbs = cm->MBs;
|
| }
|
| }
|
|
|
| @@ -3407,14 +3539,13 @@
|
| int64_t *time_stamp, int64_t *time_end, int flush) {
|
| const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
| VP9_COMMON *const cm = &cpi->common;
|
| - MACROBLOCKD *const xd = &cpi->mb.e_mbd;
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| struct vpx_usec_timer cmptimer;
|
| YV12_BUFFER_CONFIG *force_src_buffer = NULL;
|
| struct lookahead_entry *last_source = NULL;
|
| struct lookahead_entry *source = NULL;
|
| - MV_REFERENCE_FRAME ref_frame;
|
| int arf_src_index;
|
| + int i;
|
|
|
| if (is_two_pass_svc(cpi)) {
|
| #if CONFIG_SPATIAL_SVC
|
| @@ -3431,6 +3562,15 @@
|
|
|
| vp9_set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV);
|
|
|
| + // Is multi-arf enabled.
|
| + // Note that at the moment multi_arf is only configured for 2 pass VBR and
|
| + // will not work properly with svc.
|
| + if ((oxcf->pass == 2) && !cpi->use_svc &&
|
| + (cpi->oxcf.enable_auto_arf > 1))
|
| + cpi->multi_arf_allowed = 1;
|
| + else
|
| + cpi->multi_arf_allowed = 0;
|
| +
|
| // Normal defaults
|
| cm->reset_frame_context = 0;
|
| cm->refresh_frame_context = 1;
|
| @@ -3456,7 +3596,7 @@
|
| int i;
|
| // Reference a hidden frame from a lower layer
|
| for (i = cpi->svc.spatial_layer_id - 1; i >= 0; --i) {
|
| - if (oxcf->ss_play_alternate[i]) {
|
| + if (oxcf->ss_enable_auto_arf[i]) {
|
| cpi->gld_fb_idx = cpi->svc.layer_context[i].alt_ref_idx;
|
| break;
|
| }
|
| @@ -3500,6 +3640,13 @@
|
| if (source != NULL) {
|
| cm->show_frame = 1;
|
| cm->intra_only = 0;
|
| + // if the flags indicate intra frame, but if the current picture is for
|
| + // non-zero spatial layer, it should not be an intra picture.
|
| + // TODO(Won Kap): this needs to change if per-layer intra frame is
|
| + // allowed.
|
| + if ((source->flags | VPX_EFLAG_FORCE_KF) && cpi->svc.spatial_layer_id) {
|
| + source->flags &= ~(unsigned int)(VPX_EFLAG_FORCE_KF);
|
| + }
|
|
|
| // Check to see if the frame should be encoded as an arf overlay.
|
| check_src_altref(cpi, source);
|
| @@ -3544,24 +3691,12 @@
|
| vp9_restore_layer_context(cpi);
|
| }
|
|
|
| - // start with a 0 size frame
|
| - *size = 0;
|
| -
|
| - /* find a free buffer for the new frame, releasing the reference previously
|
| - * held.
|
| - */
|
| + // Find a free buffer for the new frame, releasing the reference previously
|
| + // held.
|
| cm->frame_bufs[cm->new_fb_idx].ref_count--;
|
| cm->new_fb_idx = get_free_fb(cm);
|
| + cm->cur_frame = &cm->frame_bufs[cm->new_fb_idx];
|
|
|
| - // For two pass encodes analyse the first pass stats and determine
|
| - // the bit allocation and other parameters for this frame / group of frames.
|
| - if ((oxcf->pass == 2) &&
|
| - (!cpi->use_svc ||
|
| - (is_two_pass_svc(cpi) &&
|
| - cpi->svc.encode_empty_frame_state != ENCODING))) {
|
| - vp9_rc_get_second_pass_params(cpi);
|
| - }
|
| -
|
| if (!cpi->use_svc && cpi->multi_arf_allowed) {
|
| if (cm->frame_type == KEY_FRAME) {
|
| init_buffer_indices(cpi);
|
| @@ -3571,56 +3706,23 @@
|
| }
|
| }
|
|
|
| + // Start with a 0 size frame.
|
| + *size = 0;
|
| +
|
| cpi->frame_flags = *frame_flags;
|
|
|
| - if (oxcf->pass == 2 &&
|
| - cm->current_video_frame == 0 &&
|
| - oxcf->allow_spatial_resampling &&
|
| - oxcf->rc_mode == VPX_VBR) {
|
| - // Internal scaling is triggered on the first frame.
|
| - vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
|
| - oxcf->scaled_frame_height);
|
| + if ((oxcf->pass == 2) &&
|
| + (!cpi->use_svc ||
|
| + (is_two_pass_svc(cpi) &&
|
| + cpi->svc.encode_empty_frame_state != ENCODING))) {
|
| + vp9_rc_get_second_pass_params(cpi);
|
| + } else {
|
| + set_frame_size(cpi);
|
| }
|
|
|
| - // Reset the frame pointers to the current frame size
|
| - vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
|
| - cm->width, cm->height,
|
| - cm->subsampling_x, cm->subsampling_y,
|
| -#if CONFIG_VP9_HIGHBITDEPTH
|
| - cm->use_highbitdepth,
|
| -#endif
|
| - VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
|
| + for (i = 0; i < MAX_REF_FRAMES; ++i)
|
| + cpi->scaled_ref_idx[i] = INVALID_REF_BUFFER_IDX;
|
|
|
| - alloc_util_frame_buffers(cpi);
|
| - init_motion_estimation(cpi);
|
| -
|
| - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
| - const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
|
| - YV12_BUFFER_CONFIG *const buf = &cm->frame_bufs[idx].buf;
|
| - RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1];
|
| - ref_buf->buf = buf;
|
| - ref_buf->idx = idx;
|
| -#if CONFIG_VP9_HIGHBITDEPTH
|
| - vp9_setup_scale_factors_for_frame(&ref_buf->sf,
|
| - buf->y_crop_width, buf->y_crop_height,
|
| - cm->width, cm->height,
|
| - (buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
|
| - 1 : 0);
|
| -#else
|
| - vp9_setup_scale_factors_for_frame(&ref_buf->sf,
|
| - buf->y_crop_width, buf->y_crop_height,
|
| - cm->width, cm->height);
|
| -#endif // CONFIG_VP9_HIGHBITDEPTH
|
| - if (vp9_is_scaled(&ref_buf->sf))
|
| - vp9_extend_frame_borders(buf);
|
| - }
|
| -
|
| - set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
|
| -
|
| - if (oxcf->aq_mode == VARIANCE_AQ) {
|
| - vp9_vaq_init();
|
| - }
|
| -
|
| if (oxcf->pass == 1 &&
|
| (!cpi->use_svc || is_two_pass_svc(cpi))) {
|
| const int lossless = is_lossless_requested(oxcf);
|
| @@ -3647,10 +3749,10 @@
|
| }
|
|
|
| if (cm->refresh_frame_context)
|
| - cm->frame_contexts[cm->frame_context_idx] = cm->fc;
|
| + cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
|
|
|
| - // Frame was dropped, release scaled references.
|
| - if (*size == 0) {
|
| + // No frame encoded, or frame was dropped, release scaled references.
|
| + if ((*size == 0) && (frame_is_intra_only(cm) == 0)) {
|
| release_scaled_references(cpi);
|
| }
|
|
|
|
|