| Index: source/libvpx/vp9/encoder/vp9_encoder.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_encoder.c (revision 284462)
|
| +++ source/libvpx/vp9/encoder/vp9_encoder.c (working copy)
|
| @@ -51,8 +51,6 @@
|
|
|
| void vp9_coef_tree_initialize();
|
|
|
| -#define DEFAULT_INTERP_FILTER SWITCHABLE
|
| -
|
| #define SHARP_FILTER_QTHRESH 0 /* Q threshold for 8-tap sharp filter */
|
|
|
| #define ALTREF_HIGH_PRECISION_MV 1 // Whether to use high precision mv
|
| @@ -174,7 +172,7 @@
|
| vp9_cyclic_refresh_free(cpi->cyclic_refresh);
|
| cpi->cyclic_refresh = NULL;
|
|
|
| - vp9_free_frame_buffers(cm);
|
| + vp9_free_ref_frame_buffers(cm);
|
| vp9_free_context_buffers(cm);
|
|
|
| vp9_free_frame_buffer(&cpi->last_frame_uf);
|
| @@ -200,12 +198,11 @@
|
| cpi->source_diff_var = NULL;
|
| }
|
|
|
| -#if CONFIG_FP_MB_STATS
|
| - if (cpi->use_fp_mb_stats) {
|
| - vpx_free(cpi->twopass.this_frame_mb_stats.mb_stats);
|
| - cpi->twopass.this_frame_mb_stats.mb_stats = NULL;
|
| + for (i = 0; i < MAX_LAG_BUFFERS; ++i) {
|
| + vp9_free_frame_buffer(&cpi->svc.scaled_frames[i]);
|
| }
|
| -#endif
|
| + vpx_memset(&cpi->svc.scaled_frames[0], 0,
|
| + MAX_LAG_BUFFERS * sizeof(cpi->svc.scaled_frames[0]));
|
| }
|
|
|
| static void save_coding_context(VP9_COMP *cpi) {
|
| @@ -427,7 +424,7 @@
|
|
|
| static void alloc_ref_frame_buffers(VP9_COMP *cpi) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| - if (vp9_alloc_frame_buffers(cm, cm->width, cm->height))
|
| + if (vp9_alloc_ref_frame_buffers(cm, cm->width, cm->height))
|
| vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| "Failed to allocate frame buffers");
|
| }
|
| @@ -474,8 +471,19 @@
|
| static void update_frame_size(VP9_COMP *cpi) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| MACROBLOCKD *const xd = &cpi->mb.e_mbd;
|
| - vp9_update_frame_size(cm);
|
| +
|
| + vp9_set_mb_mi(cm, cm->width, cm->height);
|
| + vp9_init_context_buffers(cm);
|
| init_macroblockd(cm, xd);
|
| +
|
| + if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
|
| + if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
|
| + cm->width, cm->height,
|
| + cm->subsampling_x, cm->subsampling_y,
|
| + VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
|
| + vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
| + "Failed to reallocate alt_ref_buffer");
|
| + }
|
| }
|
|
|
| void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
|
| @@ -628,7 +636,7 @@
|
| rc->worst_quality = cpi->oxcf.worst_allowed_q;
|
| rc->best_quality = cpi->oxcf.best_allowed_q;
|
|
|
| - cm->interp_filter = DEFAULT_INTERP_FILTER;
|
| + cm->interp_filter = cpi->sf.default_interp_filter;
|
|
|
| cm->display_width = cpi->oxcf.width;
|
| cm->display_height = cpi->oxcf.height;
|
| @@ -742,9 +750,6 @@
|
|
|
| cm->current_video_frame = 0;
|
|
|
| - // Set reference frame sign bias for ALTREF frame to 1 (for now)
|
| - cm->ref_frame_sign_bias[ALTREF_FRAME] = 1;
|
| -
|
| cpi->gold_is_last = 0;
|
| cpi->alt_is_last = 0;
|
| cpi->gold_is_alt = 0;
|
| @@ -778,11 +783,11 @@
|
| #if CONFIG_FP_MB_STATS
|
| cpi->use_fp_mb_stats = 0;
|
| if (cpi->use_fp_mb_stats) {
|
| - // a place holder for the mb stats obtained from the first pass
|
| - CHECK_MEM_ERROR(cm, cpi->twopass.this_frame_mb_stats.mb_stats,
|
| - vpx_calloc(cm->MBs * sizeof(FIRSTPASS_MB_STATS), 1));
|
| + // a place holder used to store the first pass mb stats in the first pass
|
| + CHECK_MEM_ERROR(cm, cpi->twopass.frame_mb_stats_buf,
|
| + vpx_calloc(cm->MBs * sizeof(uint8_t), 1));
|
| } else {
|
| - cpi->twopass.this_frame_mb_stats.mb_stats = NULL;
|
| + cpi->twopass.frame_mb_stats_buf = NULL;
|
| }
|
| #endif
|
|
|
| @@ -925,6 +930,19 @@
|
|
|
| vp9_init_second_pass_spatial_svc(cpi);
|
| } else {
|
| +#if CONFIG_FP_MB_STATS
|
| + if (cpi->use_fp_mb_stats) {
|
| + const size_t psz = cpi->common.MBs * sizeof(uint8_t);
|
| + const int ps = (int)(oxcf->firstpass_mb_stats_in.sz / psz);
|
| +
|
| + cpi->twopass.firstpass_mb_stats.mb_stats_start =
|
| + oxcf->firstpass_mb_stats_in.buf;
|
| + cpi->twopass.firstpass_mb_stats.mb_stats_end =
|
| + cpi->twopass.firstpass_mb_stats.mb_stats_start +
|
| + (ps - 1) * cpi->common.MBs * sizeof(uint8_t);
|
| + }
|
| +#endif
|
| +
|
| cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf;
|
| cpi->twopass.stats_in = cpi->twopass.stats_in_start;
|
| cpi->twopass.stats_in_end = &cpi->twopass.stats_in[packets - 1];
|
| @@ -1115,6 +1133,13 @@
|
| vpx_free(cpi->mbgraph_stats[i].mb_stats);
|
| }
|
|
|
| +#if CONFIG_FP_MB_STATS
|
| + if (cpi->use_fp_mb_stats) {
|
| + vpx_free(cpi->twopass.frame_mb_stats_buf);
|
| + cpi->twopass.frame_mb_stats_buf = NULL;
|
| + }
|
| +#endif
|
| +
|
| vp9_remove_common(&cpi->common);
|
| vpx_free(cpi);
|
|
|
| @@ -2057,6 +2082,22 @@
|
| 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;
|
| +
|
| + if ((cpi->pass == 2) && cpi->multi_arf_allowed) {
|
| + const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
|
| + arf_sign_bias = cpi->rc.source_alt_ref_active &&
|
| + (!cpi->refresh_alt_ref_frame ||
|
| + (gf_group->rf_level[gf_group->index] == GF_ARF_LOW));
|
| + } else {
|
| + arf_sign_bias =
|
| + (cpi->rc.source_alt_ref_active && !cpi->refresh_alt_ref_frame);
|
| + }
|
| + cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
|
| +}
|
| +
|
| static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
| size_t *size,
|
| uint8_t *dest,
|
| @@ -2089,8 +2130,8 @@
|
| cpi->zbin_mode_boost = 0;
|
| cpi->zbin_mode_boost_enabled = 0;
|
|
|
| - // Current default encoder behavior for the altref sign bias.
|
| - cm->ref_frame_sign_bias[ALTREF_FRAME] = cpi->rc.source_alt_ref_active;
|
| + // Set the arf sign bias for this frame.
|
| + set_arf_sign_bias(cpi);
|
|
|
| // Set default state for segment based loop filter update flags.
|
| cm->lf.mode_ref_delta_update = 0;
|
| @@ -2217,7 +2258,7 @@
|
| q = vp9_rc_pick_q_and_bounds(cpi, &bottom_index, &top_index);
|
|
|
| if (!frame_is_intra_only(cm)) {
|
| - cm->interp_filter = DEFAULT_INTERP_FILTER;
|
| + cm->interp_filter = cpi->sf.default_interp_filter;
|
| /* TODO: Decide this more intelligently */
|
| vp9_set_high_precision_mv(cpi, q < HIGH_PRECISION_MV_QTHRESH);
|
| }
|
| @@ -2486,7 +2527,7 @@
|
| static int get_arf_src_index(VP9_COMP *cpi) {
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| int arf_src_index = 0;
|
| - if (is_altref_enabled(&cpi->oxcf)) {
|
| + if (is_altref_enabled(cpi)) {
|
| if (cpi->pass == 2) {
|
| const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
|
| if (gf_group->update_type[gf_group->index] == ARF_UPDATE) {
|
| @@ -2565,13 +2606,27 @@
|
| #ifdef CONFIG_SPATIAL_SVC
|
| if (is_spatial_svc)
|
| cpi->source = vp9_svc_lookahead_peek(cpi, cpi->lookahead,
|
| - arf_src_index, 1);
|
| + arf_src_index, 0);
|
| else
|
| #endif
|
| cpi->source = vp9_lookahead_peek(cpi->lookahead, arf_src_index);
|
| if (cpi->source != NULL) {
|
| cpi->alt_ref_source = cpi->source;
|
|
|
| +#ifdef CONFIG_SPATIAL_SVC
|
| + if (is_spatial_svc && cpi->svc.spatial_layer_id > 0) {
|
| + int i;
|
| + // Reference a hidden frame from a lower layer
|
| + for (i = cpi->svc.spatial_layer_id - 1; i >= 0; --i) {
|
| + if (cpi->oxcf.ss_play_alternate[i]) {
|
| + cpi->gld_fb_idx = cpi->svc.layer_context[i].alt_ref_idx;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + cpi->svc.layer_context[cpi->svc.spatial_layer_id].has_alt_frame = 1;
|
| +#endif
|
| +
|
| if (cpi->oxcf.arnr_max_frames > 0) {
|
| // Produce the filtered ARF frame.
|
| vp9_temporal_filter(cpi, arf_src_index);
|
| @@ -2787,6 +2842,8 @@
|
| PSNR_STATS psnr2;
|
| double frame_ssim2 = 0, weight = 0;
|
| #if CONFIG_VP9_POSTPROC
|
| + // TODO(agrange) Add resizing of post-proc buffer in here when the
|
| + // encoder is changed to use on-demand buffer allocation.
|
| vp9_deblock(cm->frame_to_show, &cm->post_proc_buffer,
|
| cm->lf.filter_level * 10 / 6);
|
| #endif
|
| @@ -2904,10 +2961,11 @@
|
| // always go to the next whole number
|
| cm->width = (hs - 1 + cpi->oxcf.width * hr) / hs;
|
| cm->height = (vs - 1 + cpi->oxcf.height * vr) / vs;
|
| -
|
| assert(cm->width <= cpi->initial_width);
|
| assert(cm->height <= cpi->initial_height);
|
| +
|
| update_frame_size(cpi);
|
| +
|
| return 0;
|
| }
|
|
|
| @@ -2940,10 +2998,11 @@
|
| printf("Warning: Desired height too large, changed to %d\n", cm->height);
|
| }
|
| }
|
| -
|
| assert(cm->width <= cpi->initial_width);
|
| assert(cm->height <= cpi->initial_height);
|
| +
|
| update_frame_size(cpi);
|
| +
|
| return 0;
|
| }
|
|
|
|
|