| Index: source/libvpx/vp9/encoder/vp9_firstpass.c
|
| diff --git a/source/libvpx/vp9/encoder/vp9_firstpass.c b/source/libvpx/vp9/encoder/vp9_firstpass.c
|
| index 4c45a79263904f4bfff5e480b40b638afaff18a2..6c8bbdb6d5d8d1815afee9e13f9bc534040444ea 100644
|
| --- a/source/libvpx/vp9/encoder/vp9_firstpass.c
|
| +++ b/source/libvpx/vp9/encoder/vp9_firstpass.c
|
| @@ -57,6 +57,8 @@
|
| #define SVC_FACTOR_PT_LOW 0.45
|
| #define DARK_THRESH 64
|
| #define DEFAULT_GRP_WEIGHT 1.0
|
| +#define RC_FACTOR_MIN 0.75
|
| +#define RC_FACTOR_MAX 1.75
|
|
|
| #define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001)
|
|
|
| @@ -64,12 +66,6 @@
|
| unsigned int arf_count = 0;
|
| #endif
|
|
|
| -static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
|
| - YV12_BUFFER_CONFIG temp = *a;
|
| - *a = *b;
|
| - *b = temp;
|
| -}
|
| -
|
| // Resets the first pass file to the given position using a relative seek from
|
| // the current position.
|
| static void reset_fpf_position(TWO_PASS *p,
|
| @@ -463,12 +459,6 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| int i;
|
|
|
| int recon_yoffset, recon_uvoffset;
|
| - YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
|
| - YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
|
| - YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
|
| - int recon_y_stride = lst_yv12->y_stride;
|
| - int recon_uv_stride = lst_yv12->uv_stride;
|
| - int uv_mb_height = 16 >> (lst_yv12->y_height > lst_yv12->uv_height);
|
| int64_t intra_error = 0;
|
| int64_t coded_error = 0;
|
| int64_t sr_coded_error = 0;
|
| @@ -486,11 +476,22 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| MV lastmv = {0, 0};
|
| TWO_PASS *twopass = &cpi->twopass;
|
| const MV zero_mv = {0, 0};
|
| + int recon_y_stride, recon_uv_stride, uv_mb_height;
|
| +
|
| + YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
|
| + YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
|
| + YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
|
| const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
|
| +
|
| LAYER_CONTEXT *const lc = is_two_pass_svc(cpi) ?
|
| &cpi->svc.layer_context[cpi->svc.spatial_layer_id] : NULL;
|
| double intra_factor;
|
| double brightness_factor;
|
| + BufferPool *const pool = cm->buffer_pool;
|
| +
|
| + // First pass code requires valid last and new frame buffers.
|
| + assert(new_yv12 != NULL);
|
| + assert((lc != NULL) || frame_is_intra_only(cm) || (lst_yv12 != NULL));
|
|
|
| #if CONFIG_FP_MB_STATS
|
| if (cpi->use_fp_mb_stats) {
|
| @@ -535,21 +536,14 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| }
|
|
|
| if (cpi->ref_frame_flags & VP9_GOLD_FLAG) {
|
| - BufferPool *const pool = cm->buffer_pool;
|
| - const int ref_idx =
|
| - cm->ref_frame_map[get_ref_frame_idx(cpi, GOLDEN_FRAME)];
|
| - const int scaled_idx = cpi->scaled_ref_idx[GOLDEN_FRAME - 1];
|
| -
|
| - gld_yv12 = (scaled_idx != ref_idx) ? &pool->frame_bufs[scaled_idx].buf :
|
| - get_ref_frame_buffer(cpi, GOLDEN_FRAME);
|
| + gld_yv12 = vp9_get_scaled_ref_frame(cpi, GOLDEN_FRAME);
|
| + if (gld_yv12 == NULL) {
|
| + gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
|
| + }
|
| } else {
|
| gld_yv12 = NULL;
|
| }
|
|
|
| - recon_y_stride = new_yv12->y_stride;
|
| - recon_uv_stride = new_yv12->uv_stride;
|
| - uv_mb_height = 16 >> (new_yv12->y_height > new_yv12->uv_height);
|
| -
|
| set_ref_ptrs(cm, xd,
|
| (cpi->ref_frame_flags & VP9_LAST_FLAG) ? LAST_FRAME: NONE,
|
| (cpi->ref_frame_flags & VP9_GOLD_FLAG) ? GOLDEN_FRAME : NONE);
|
| @@ -561,9 +555,12 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
|
|
|
| vp9_setup_src_planes(x, cpi->Source, 0, 0);
|
| - vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
|
| vp9_setup_dst_planes(xd->plane, new_yv12, 0, 0);
|
|
|
| + if (!frame_is_intra_only(cm)) {
|
| + vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
|
| + }
|
| +
|
| xd->mi = cm->mi;
|
| xd->mi[0].src_mi = &xd->mi[0];
|
|
|
| @@ -583,6 +580,10 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| // Tiling is ignored in the first pass.
|
| vp9_tile_init(&tile, cm, 0, 0);
|
|
|
| + recon_y_stride = new_yv12->y_stride;
|
| + recon_uv_stride = new_yv12->uv_stride;
|
| + uv_mb_height = 16 >> (new_yv12->y_height > new_yv12->uv_height);
|
| +
|
| for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
|
| MV best_ref_mv = {0, 0};
|
|
|
| @@ -1018,7 +1019,8 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| ((twopass->this_frame_stats.intra_error /
|
| DOUBLE_DIVIDE_CHECK(twopass->this_frame_stats.coded_error)) > 2.0))) {
|
| if (gld_yv12 != NULL) {
|
| - vp8_yv12_copy_frame(lst_yv12, gld_yv12);
|
| + ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
|
| + cm->ref_frame_map[cpi->lst_fb_idx]);
|
| }
|
| twopass->sr_update_lag = 1;
|
| } else {
|
| @@ -1030,14 +1032,17 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| if (lc != NULL) {
|
| vp9_update_reference_frames(cpi);
|
| } else {
|
| - // Swap frame pointers so last frame refers to the frame we just compressed.
|
| - swap_yv12(lst_yv12, new_yv12);
|
| + // The frame we just compressed now becomes the last frame.
|
| + ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx],
|
| + cm->new_fb_idx);
|
| }
|
|
|
| // Special case for the first frame. Copy into the GF buffer as a second
|
| // reference.
|
| - if (cm->current_video_frame == 0 && gld_yv12 != NULL && lc == NULL) {
|
| - vp8_yv12_copy_frame(lst_yv12, gld_yv12);
|
| + if (cm->current_video_frame == 0 && cpi->gld_fb_idx != INVALID_IDX &&
|
| + lc == NULL) {
|
| + ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
|
| + cm->ref_frame_map[cpi->lst_fb_idx]);
|
| }
|
|
|
| // Use this to see what the first pass reconstruction looks like.
|
| @@ -1960,16 +1965,21 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
| const int vbr_group_bits_per_frame =
|
| (int)(gf_group_bits / rc->baseline_gf_interval);
|
| const double group_av_err = gf_group_raw_error / rc->baseline_gf_interval;
|
| - const int tmp_q =
|
| - get_twopass_worst_quality(cpi, group_av_err, vbr_group_bits_per_frame,
|
| - twopass->kfgroup_inter_fraction);
|
| -
|
| - if (tmp_q < twopass->baseline_active_worst_quality) {
|
| - twopass->active_worst_quality =
|
| - (tmp_q + twopass->baseline_active_worst_quality + 1) / 2;
|
| + int tmp_q;
|
| + // rc factor is a weight factor that corrects for local rate control drift.
|
| + double rc_factor = 1.0;
|
| + if (rc->rate_error_estimate > 0) {
|
| + rc_factor = MAX(RC_FACTOR_MIN,
|
| + (double)(100 - rc->rate_error_estimate) / 100.0);
|
| } else {
|
| - twopass->active_worst_quality = tmp_q;
|
| + rc_factor = MIN(RC_FACTOR_MAX,
|
| + (double)(100 - rc->rate_error_estimate) / 100.0);
|
| }
|
| + tmp_q =
|
| + get_twopass_worst_quality(cpi, group_av_err, vbr_group_bits_per_frame,
|
| + twopass->kfgroup_inter_fraction * rc_factor);
|
| + twopass->active_worst_quality =
|
| + MAX(tmp_q, twopass->active_worst_quality >> 1);
|
| }
|
| #endif
|
|
|
| @@ -2577,7 +2587,7 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
| subtract_stats(&twopass->total_left_stats, &this_frame);
|
| }
|
|
|
| -#define MINQ_ADJ_LIMIT 32
|
| +#define MINQ_ADJ_LIMIT 48
|
| void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
| TWO_PASS *const twopass = &cpi->twopass;
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| @@ -2610,8 +2620,7 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
| // Increment the gf group index ready for the next frame.
|
| ++twopass->gf_group.index;
|
|
|
| - // If the rate control is drifting consider adjustment ot min or maxq.
|
| - // Only make adjustments on gf/arf
|
| + // If the rate control is drifting consider adjustment to min or maxq.
|
| if ((cpi->oxcf.rc_mode == VPX_VBR) &&
|
| (cpi->twopass.gf_zeromotion_pct < VLOW_MOTION_THRESHOLD) &&
|
| !cpi->rc.is_src_frame_alt_ref) {
|
| @@ -2640,6 +2649,7 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
| else if (rc->rolling_target_bits > rc->rolling_actual_bits)
|
| --twopass->extend_maxq;
|
| }
|
| +
|
| twopass->extend_minq = clamp(twopass->extend_minq, 0, MINQ_ADJ_LIMIT);
|
| twopass->extend_maxq = clamp(twopass->extend_maxq, 0, maxq_adj_limit);
|
| }
|
|
|