| Index: source/libvpx/vp9/encoder/vp9_ratectrl.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_ratectrl.c (revision 263011)
|
| +++ source/libvpx/vp9/encoder/vp9_ratectrl.c (working copy)
|
| @@ -27,14 +27,14 @@
|
| #include "vp9/encoder/vp9_encodemv.h"
|
| #include "vp9/encoder/vp9_ratectrl.h"
|
|
|
| +#define DEFAULT_KF_BOOST 2000
|
| +#define DEFAULT_GF_BOOST 2000
|
| +
|
| #define LIMIT_QRANGE_FOR_ALTREF_AND_KEY 1
|
|
|
| #define MIN_BPB_FACTOR 0.005
|
| #define MAX_BPB_FACTOR 50
|
|
|
| -// Bits Per MB at different Q (Multiplied by 512)
|
| -#define BPER_MB_NORMBITS 9
|
| -
|
| // Tables relating active max Q to active min Q
|
| static int kf_low_motion_minq[QINDEX_RANGE];
|
| static int kf_high_motion_minq[QINDEX_RANGE];
|
| @@ -52,10 +52,9 @@
|
| // formulaic approach to facilitate easier adjustment of the Q tables.
|
| // The formulae were derived from computing a 3rd order polynomial best
|
| // fit to the original data (after plotting real maxq vs minq (not q index))
|
| -static int calculate_minq_index(double maxq,
|
| - double x3, double x2, double x1, double c) {
|
| +static int get_minq_index(double maxq, double x3, double x2, double x1) {
|
| int i;
|
| - const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq + c,
|
| + const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq,
|
| maxq);
|
|
|
| // Special case handling to deal with the step from q2.0
|
| @@ -63,57 +62,26 @@
|
| if (minqtarget <= 2.0)
|
| return 0;
|
|
|
| - for (i = 0; i < QINDEX_RANGE; i++) {
|
| + for (i = 0; i < QINDEX_RANGE; i++)
|
| if (minqtarget <= vp9_convert_qindex_to_q(i))
|
| return i;
|
| - }
|
|
|
| return QINDEX_RANGE - 1;
|
| }
|
|
|
| -void vp9_rc_init_minq_luts(void) {
|
| +void vp9_rc_init_minq_luts() {
|
| int i;
|
|
|
| for (i = 0; i < QINDEX_RANGE; i++) {
|
| const double maxq = vp9_convert_qindex_to_q(i);
|
|
|
| -
|
| - kf_low_motion_minq[i] = calculate_minq_index(maxq,
|
| - 0.000001,
|
| - -0.0004,
|
| - 0.15,
|
| - 0.0);
|
| - kf_high_motion_minq[i] = calculate_minq_index(maxq,
|
| - 0.000002,
|
| - -0.0012,
|
| - 0.50,
|
| - 0.0);
|
| -
|
| - gf_low_motion_minq[i] = calculate_minq_index(maxq,
|
| - 0.0000015,
|
| - -0.0009,
|
| - 0.32,
|
| - 0.0);
|
| - gf_high_motion_minq[i] = calculate_minq_index(maxq,
|
| - 0.0000021,
|
| - -0.00125,
|
| - 0.50,
|
| - 0.0);
|
| - afq_low_motion_minq[i] = calculate_minq_index(maxq,
|
| - 0.0000015,
|
| - -0.0009,
|
| - 0.33,
|
| - 0.0);
|
| - afq_high_motion_minq[i] = calculate_minq_index(maxq,
|
| - 0.0000021,
|
| - -0.00125,
|
| - 0.55,
|
| - 0.0);
|
| - inter_minq[i] = calculate_minq_index(maxq,
|
| - 0.00000271,
|
| - -0.00113,
|
| - 0.75,
|
| - 0.0);
|
| + kf_low_motion_minq[i] = get_minq_index(maxq, 0.000001, -0.0004, 0.15);
|
| + kf_high_motion_minq[i] = get_minq_index(maxq, 0.000002, -0.0012, 0.50);
|
| + gf_low_motion_minq[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.32);
|
| + gf_high_motion_minq[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.50);
|
| + afq_low_motion_minq[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.33);
|
| + afq_high_motion_minq[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55);
|
| + inter_minq[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.75);
|
| }
|
| }
|
|
|
| @@ -135,79 +103,10 @@
|
| return (int)(0.5 + (enumerator * correction_factor / q));
|
| }
|
|
|
| -void vp9_save_coding_context(VP9_COMP *cpi) {
|
| - CODING_CONTEXT *const cc = &cpi->coding_context;
|
| - VP9_COMMON *cm = &cpi->common;
|
| -
|
| - // Stores a snapshot of key state variables which can subsequently be
|
| - // restored with a call to vp9_restore_coding_context. These functions are
|
| - // intended for use in a re-code loop in vp9_compress_frame where the
|
| - // quantizer value is adjusted between loop iterations.
|
| - vp9_copy(cc->nmvjointcost, cpi->mb.nmvjointcost);
|
| - vp9_copy(cc->nmvcosts, cpi->mb.nmvcosts);
|
| - vp9_copy(cc->nmvcosts_hp, cpi->mb.nmvcosts_hp);
|
| -
|
| - vp9_copy(cc->segment_pred_probs, cm->seg.pred_probs);
|
| -
|
| - vpx_memcpy(cpi->coding_context.last_frame_seg_map_copy,
|
| - cm->last_frame_seg_map, (cm->mi_rows * cm->mi_cols));
|
| -
|
| - 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;
|
| -}
|
| -
|
| -void vp9_restore_coding_context(VP9_COMP *cpi) {
|
| - CODING_CONTEXT *const cc = &cpi->coding_context;
|
| - VP9_COMMON *cm = &cpi->common;
|
| -
|
| - // Restore key state variables to the snapshot state stored in the
|
| - // previous call to vp9_save_coding_context.
|
| - vp9_copy(cpi->mb.nmvjointcost, cc->nmvjointcost);
|
| - vp9_copy(cpi->mb.nmvcosts, cc->nmvcosts);
|
| - vp9_copy(cpi->mb.nmvcosts_hp, cc->nmvcosts_hp);
|
| -
|
| - vp9_copy(cm->seg.pred_probs, cc->segment_pred_probs);
|
| -
|
| - vpx_memcpy(cm->last_frame_seg_map,
|
| - cpi->coding_context.last_frame_seg_map_copy,
|
| - (cm->mi_rows * cm->mi_cols));
|
| -
|
| - 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;
|
| -}
|
| -
|
| -void vp9_setup_key_frame(VP9_COMP *cpi) {
|
| - VP9_COMMON *cm = &cpi->common;
|
| -
|
| - vp9_setup_past_independence(cm);
|
| -
|
| - /* All buffers are implicitly updated on key frames. */
|
| - cpi->refresh_golden_frame = 1;
|
| - cpi->refresh_alt_ref_frame = 1;
|
| -}
|
| -
|
| -void vp9_setup_inter_frame(VP9_COMP *cpi) {
|
| - VP9_COMMON *cm = &cpi->common;
|
| - if (cm->error_resilient_mode || cm->intra_only)
|
| - vp9_setup_past_independence(cm);
|
| -
|
| - assert(cm->frame_context_idx < FRAME_CONTEXTS);
|
| - cm->fc = cm->frame_contexts[cm->frame_context_idx];
|
| -}
|
| -
|
| -static int estimate_bits_at_q(int frame_kind, int q, int mbs,
|
| +static int estimate_bits_at_q(FRAME_TYPE frame_type, int q, int mbs,
|
| double correction_factor) {
|
| - const int bpm = (int)(vp9_rc_bits_per_mb(frame_kind, q, correction_factor));
|
| -
|
| - // Attempt to retain reasonable accuracy without overflow. The cutoff is
|
| - // chosen such that the maximum product of Bpm and MBs fits 31 bits. The
|
| - // largest Bpm takes 20 bits.
|
| - return (mbs > (1 << 11)) ? (bpm >> BPER_MB_NORMBITS) * mbs
|
| - : (bpm * mbs) >> BPER_MB_NORMBITS;
|
| + const int bpm = (int)(vp9_rc_bits_per_mb(frame_type, q, correction_factor));
|
| + return ((uint64_t)bpm * mbs) >> BPER_MB_NORMBITS;
|
| }
|
|
|
| int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) {
|
| @@ -244,13 +143,12 @@
|
|
|
|
|
| // Update the buffer level for higher layers, given the encoded current layer.
|
| -static void update_layer_buffer_level(VP9_COMP *const cpi,
|
| - int encoded_frame_size) {
|
| +static void update_layer_buffer_level(SVC *svc, int encoded_frame_size) {
|
| int temporal_layer = 0;
|
| - int current_temporal_layer = cpi->svc.temporal_layer_id;
|
| + int current_temporal_layer = svc->temporal_layer_id;
|
| for (temporal_layer = current_temporal_layer + 1;
|
| - temporal_layer < cpi->svc.number_temporal_layers; ++temporal_layer) {
|
| - LAYER_CONTEXT *lc = &cpi->svc.layer_context[temporal_layer];
|
| + temporal_layer < svc->number_temporal_layers; ++temporal_layer) {
|
| + LAYER_CONTEXT *lc = &svc->layer_context[temporal_layer];
|
| RATE_CONTROL *lrc = &lc->rc;
|
| int bits_off_for_this_layer = (int)(lc->target_bandwidth / lc->framerate -
|
| encoded_frame_size);
|
| @@ -280,10 +178,60 @@
|
| rc->buffer_level = rc->bits_off_target;
|
|
|
| if (cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
|
| - update_layer_buffer_level(cpi, encoded_frame_size);
|
| + update_layer_buffer_level(&cpi->svc, encoded_frame_size);
|
| }
|
| }
|
|
|
| +void vp9_rc_init(const VP9_CONFIG *oxcf, int pass, RATE_CONTROL *rc) {
|
| + if (pass == 0 && oxcf->end_usage == USAGE_STREAM_FROM_SERVER) {
|
| + rc->avg_frame_qindex[0] = oxcf->worst_allowed_q;
|
| + rc->avg_frame_qindex[1] = oxcf->worst_allowed_q;
|
| + rc->avg_frame_qindex[2] = oxcf->worst_allowed_q;
|
| + } else {
|
| + rc->avg_frame_qindex[0] = (oxcf->worst_allowed_q +
|
| + oxcf->best_allowed_q) / 2;
|
| + rc->avg_frame_qindex[1] = (oxcf->worst_allowed_q +
|
| + oxcf->best_allowed_q) / 2;
|
| + rc->avg_frame_qindex[2] = (oxcf->worst_allowed_q +
|
| + oxcf->best_allowed_q) / 2;
|
| + }
|
| +
|
| + rc->last_q[0] = oxcf->best_allowed_q;
|
| + rc->last_q[1] = oxcf->best_allowed_q;
|
| + rc->last_q[2] = oxcf->best_allowed_q;
|
| +
|
| + rc->buffer_level = oxcf->starting_buffer_level;
|
| + rc->bits_off_target = oxcf->starting_buffer_level;
|
| +
|
| + rc->rolling_target_bits = rc->av_per_frame_bandwidth;
|
| + rc->rolling_actual_bits = rc->av_per_frame_bandwidth;
|
| + rc->long_rolling_target_bits = rc->av_per_frame_bandwidth;
|
| + rc->long_rolling_actual_bits = rc->av_per_frame_bandwidth;
|
| +
|
| + rc->total_actual_bits = 0;
|
| + rc->total_target_vs_actual = 0;
|
| +
|
| + rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
|
| + rc->frames_since_key = 8; // Sensible default for first frame.
|
| + rc->this_key_frame_forced = 0;
|
| + rc->next_key_frame_forced = 0;
|
| + rc->source_alt_ref_pending = 0;
|
| + rc->source_alt_ref_active = 0;
|
| +
|
| + rc->frames_till_gf_update_due = 0;
|
| +
|
| + rc->ni_av_qi = oxcf->worst_allowed_q;
|
| + rc->ni_tot_qi = 0;
|
| + rc->ni_frames = 0;
|
| +
|
| + rc->tot_q = 0.0;
|
| + rc->avg_q = vp9_convert_qindex_to_q(oxcf->worst_allowed_q);
|
| +
|
| + rc->rate_correction_factor = 1.0;
|
| + rc->key_frame_rate_correction_factor = 1.0;
|
| + rc->gf_rate_correction_factor = 1.0;
|
| +}
|
| +
|
| int vp9_rc_drop_frame(VP9_COMP *cpi) {
|
| const VP9_CONFIG *oxcf = &cpi->oxcf;
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| @@ -327,6 +275,7 @@
|
| return cpi->rc.key_frame_rate_correction_factor;
|
| } else {
|
| if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) &&
|
| + !cpi->rc.is_src_frame_alt_ref &&
|
| !(cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER))
|
| return cpi->rc.gf_rate_correction_factor;
|
| else
|
| @@ -339,6 +288,7 @@
|
| cpi->rc.key_frame_rate_correction_factor = factor;
|
| } else {
|
| if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) &&
|
| + !cpi->rc.is_src_frame_alt_ref &&
|
| !(cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER))
|
| cpi->rc.gf_rate_correction_factor = factor;
|
| else
|
| @@ -347,7 +297,7 @@
|
| }
|
|
|
| void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) {
|
| - const int q = cpi->common.base_qindex;
|
| + const VP9_COMMON *const cm = &cpi->common;
|
| int correction_factor = 100;
|
| double rate_correction_factor = get_rate_correction_factor(cpi);
|
| double adjustment_limit;
|
| @@ -360,8 +310,8 @@
|
| // Work out how big we would have expected the frame to be at this Q given
|
| // the current correction factor.
|
| // Stay in double to avoid int overflow when values are large
|
| - projected_size_based_on_q = estimate_bits_at_q(cpi->common.frame_type, q,
|
| - cpi->common.MBs,
|
| + projected_size_based_on_q = estimate_bits_at_q(cm->frame_type,
|
| + cm->base_qindex, cm->MBs,
|
| rate_correction_factor);
|
| // Work out a size correction factor.
|
| if (projected_size_based_on_q > 0)
|
| @@ -385,20 +335,18 @@
|
|
|
| if (correction_factor > 102) {
|
| // We are not already at the worst allowable quality
|
| - correction_factor =
|
| - (int)(100 + ((correction_factor - 100) * adjustment_limit));
|
| - rate_correction_factor =
|
| - ((rate_correction_factor * correction_factor) / 100);
|
| + correction_factor = (int)(100 + ((correction_factor - 100) *
|
| + adjustment_limit));
|
| + rate_correction_factor = (rate_correction_factor * correction_factor) / 100;
|
|
|
| // Keep rate_correction_factor within limits
|
| if (rate_correction_factor > MAX_BPB_FACTOR)
|
| rate_correction_factor = MAX_BPB_FACTOR;
|
| } else if (correction_factor < 99) {
|
| // We are not already at the best allowable quality
|
| - correction_factor =
|
| - (int)(100 - ((100 - correction_factor) * adjustment_limit));
|
| - rate_correction_factor =
|
| - ((rate_correction_factor * correction_factor) / 100);
|
| + correction_factor = (int)(100 - ((100 - correction_factor) *
|
| + adjustment_limit));
|
| + rate_correction_factor = (rate_correction_factor * correction_factor) / 100;
|
|
|
| // Keep rate_correction_factor within limits
|
| if (rate_correction_factor < MIN_BPB_FACTOR)
|
| @@ -419,11 +367,8 @@
|
|
|
| // Calculate required scaling factor based on target frame size and size of
|
| // frame produced using previous Q.
|
| - if (target_bits_per_frame >= (INT_MAX >> BPER_MB_NORMBITS))
|
| - // Case where we would overflow int
|
| - target_bits_per_mb = (target_bits_per_frame / cm->MBs) << BPER_MB_NORMBITS;
|
| - else
|
| - target_bits_per_mb = (target_bits_per_frame << BPER_MB_NORMBITS) / cm->MBs;
|
| + target_bits_per_mb =
|
| + ((uint64_t)target_bits_per_frame << BPER_MB_NORMBITS) / cm->MBs;
|
|
|
| i = active_best_quality;
|
|
|
| @@ -462,33 +407,25 @@
|
| }
|
|
|
| static int calc_active_worst_quality_one_pass_vbr(const VP9_COMP *cpi) {
|
| + const RATE_CONTROL *const rc = &cpi->rc;
|
| + const unsigned int curr_frame = cpi->common.current_video_frame;
|
| int active_worst_quality;
|
| +
|
| if (cpi->common.frame_type == KEY_FRAME) {
|
| - if (cpi->common.current_video_frame == 0) {
|
| - active_worst_quality = cpi->rc.worst_quality;
|
| - } else {
|
| - // Choose active worst quality twice as large as the last q.
|
| - active_worst_quality = cpi->rc.last_q[KEY_FRAME] * 2;
|
| - }
|
| - } else if (!cpi->rc.is_src_frame_alt_ref &&
|
| - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
|
| - if (cpi->common.current_video_frame == 1) {
|
| - active_worst_quality = cpi->rc.last_q[KEY_FRAME] * 5 / 4;
|
| - } else {
|
| - // Choose active worst quality twice as large as the last q.
|
| - active_worst_quality = cpi->rc.last_q[INTER_FRAME];
|
| - }
|
| + active_worst_quality = curr_frame == 0 ? rc->worst_quality
|
| + : rc->last_q[KEY_FRAME] * 2;
|
| } else {
|
| - if (cpi->common.current_video_frame == 1) {
|
| - active_worst_quality = cpi->rc.last_q[KEY_FRAME] * 2;
|
| + if (!rc->is_src_frame_alt_ref &&
|
| + (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
|
| + active_worst_quality = curr_frame == 1 ? rc->last_q[KEY_FRAME] * 5 / 4
|
| + : rc->last_q[INTER_FRAME];
|
| } else {
|
| - // Choose active worst quality twice as large as the last q.
|
| - active_worst_quality = cpi->rc.last_q[INTER_FRAME] * 2;
|
| + active_worst_quality = curr_frame == 1 ? rc->last_q[KEY_FRAME] * 2
|
| + : rc->last_q[INTER_FRAME] * 2;
|
| }
|
| }
|
| - if (active_worst_quality > cpi->rc.worst_quality)
|
| - active_worst_quality = cpi->rc.worst_quality;
|
| - return active_worst_quality;
|
| +
|
| + return MIN(active_worst_quality, rc->worst_quality);
|
| }
|
|
|
| // Adjust active_worst_quality level based on buffer level.
|
| @@ -498,6 +435,7 @@
|
| // If buffer is below the optimal level, let the active_worst_quality go from
|
| // ambient Q (at buffer = optimal level) to worst_quality level
|
| // (at buffer = critical level).
|
| + const VP9_COMMON *const cm = &cpi->common;
|
| const VP9_CONFIG *oxcf = &cpi->oxcf;
|
| const RATE_CONTROL *rc = &cpi->rc;
|
| // Buffer level below which we push active_worst to worst_quality.
|
| @@ -505,9 +443,9 @@
|
| int64_t buff_lvl_step = 0;
|
| int adjustment = 0;
|
| int active_worst_quality;
|
| - if (cpi->common.frame_type == KEY_FRAME)
|
| + if (cm->frame_type == KEY_FRAME)
|
| return rc->worst_quality;
|
| - if (cpi->common.current_video_frame > 1)
|
| + if (cm->current_video_frame > 1)
|
| active_worst_quality = MIN(rc->worst_quality,
|
| rc->avg_frame_qindex[INTER_FRAME] * 5 / 4);
|
| else
|
| @@ -561,7 +499,7 @@
|
| if (rc->this_key_frame_forced) {
|
| int qindex = rc->last_boosted_qindex;
|
| double last_boosted_q = vp9_convert_qindex_to_q(qindex);
|
| - int delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q,
|
| + int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
|
| (last_boosted_q * 0.75));
|
| active_best_quality = MAX(qindex + delta_qindex, rc->best_quality);
|
| } else if (cm->current_video_frame > 0) {
|
| @@ -583,10 +521,11 @@
|
| // Convert the adjustment factor to a qindex delta
|
| // on active_best_quality.
|
| q_val = vp9_convert_qindex_to_q(active_best_quality);
|
| - active_best_quality += vp9_compute_qdelta(cpi, q_val, q_val *
|
| - q_adj_factor);
|
| + active_best_quality += vp9_compute_qdelta(rc, q_val,
|
| + q_val * q_adj_factor);
|
| }
|
| } else if (!rc->is_src_frame_alt_ref &&
|
| + !cpi->use_svc &&
|
| (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
|
| // Use the lower of active_worst_quality and recent
|
| // average Q as basis for GF/ARF best Q limit unless last frame was
|
| @@ -639,7 +578,7 @@
|
| active_best_quality, active_worst_quality);
|
| if (q > *top_index) {
|
| // Special case when we are targeting the max allowed rate
|
| - if (cpi->rc.this_frame_target >= cpi->rc.max_frame_bandwidth)
|
| + if (rc->this_frame_target >= rc->max_frame_bandwidth)
|
| *top_index = q;
|
| else
|
| q = *top_index;
|
| @@ -672,8 +611,8 @@
|
| if (rc->this_key_frame_forced) {
|
| int qindex = rc->last_boosted_qindex;
|
| double last_boosted_q = vp9_convert_qindex_to_q(qindex);
|
| - int delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q,
|
| - (last_boosted_q * 0.75));
|
| + int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
|
| + last_boosted_q * 0.75);
|
| active_best_quality = MAX(qindex + delta_qindex, rc->best_quality);
|
| } else if (cm->current_video_frame > 0) {
|
| // not first frame of one pass and kf_boost is set
|
| @@ -694,15 +633,15 @@
|
| // Convert the adjustment factor to a qindex delta
|
| // on active_best_quality.
|
| q_val = vp9_convert_qindex_to_q(active_best_quality);
|
| - active_best_quality += vp9_compute_qdelta(cpi, q_val, q_val *
|
| - q_adj_factor);
|
| + active_best_quality += vp9_compute_qdelta(rc, q_val,
|
| + q_val * q_adj_factor);
|
| }
|
| #else
|
| double current_q;
|
| // Force the KF quantizer to be 30% of the active_worst_quality.
|
| current_q = vp9_convert_qindex_to_q(active_worst_quality);
|
| active_best_quality = active_worst_quality
|
| - + vp9_compute_qdelta(cpi, current_q, current_q * 0.3);
|
| + + vp9_compute_qdelta(rc, current_q, current_q * 0.3);
|
| #endif
|
| } else if (!rc->is_src_frame_alt_ref &&
|
| (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
|
| @@ -805,7 +744,7 @@
|
| active_best_quality, active_worst_quality);
|
| if (q > *top_index) {
|
| // Special case when we are targeting the max allowed rate
|
| - if (cpi->rc.this_frame_target >= cpi->rc.max_frame_bandwidth)
|
| + if (rc->this_frame_target >= rc->max_frame_bandwidth)
|
| *top_index = q;
|
| else
|
| q = *top_index;
|
| @@ -821,7 +760,7 @@
|
| assert(level >= 0);
|
| new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level)));
|
| q = active_worst_quality +
|
| - vp9_compute_qdelta(cpi, current_q, new_q);
|
| + vp9_compute_qdelta(rc, current_q, new_q);
|
|
|
| *bottom_index = q;
|
| *top_index = q;
|
| @@ -854,8 +793,8 @@
|
| if (rc->this_key_frame_forced) {
|
| int qindex = rc->last_boosted_qindex;
|
| double last_boosted_q = vp9_convert_qindex_to_q(qindex);
|
| - int delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q,
|
| - (last_boosted_q * 0.75));
|
| + int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
|
| + last_boosted_q * 0.75);
|
| active_best_quality = MAX(qindex + delta_qindex, rc->best_quality);
|
| } else {
|
| // Not forced keyframe.
|
| @@ -879,15 +818,15 @@
|
| // Convert the adjustment factor to a qindex delta
|
| // on active_best_quality.
|
| q_val = vp9_convert_qindex_to_q(active_best_quality);
|
| - active_best_quality += vp9_compute_qdelta(cpi, q_val, q_val *
|
| - q_adj_factor);
|
| + active_best_quality += vp9_compute_qdelta(rc, q_val,
|
| + q_val * q_adj_factor);
|
| }
|
| #else
|
| double current_q;
|
| // Force the KF quantizer to be 30% of the active_worst_quality.
|
| current_q = vp9_convert_qindex_to_q(active_worst_quality);
|
| active_best_quality = active_worst_quality
|
| - + vp9_compute_qdelta(cpi, current_q, current_q * 0.3);
|
| + + vp9_compute_qdelta(rc, current_q, current_q * 0.3);
|
| #endif
|
| } else if (!rc->is_src_frame_alt_ref &&
|
| (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
|
| @@ -988,7 +927,7 @@
|
| active_best_quality, active_worst_quality);
|
| if (q > *top_index) {
|
| // Special case when we are targeting the max allowed rate.
|
| - if (cpi->rc.this_frame_target >= cpi->rc.max_frame_bandwidth)
|
| + if (rc->this_frame_target >= rc->max_frame_bandwidth)
|
| *top_index = q;
|
| else
|
| q = *top_index;
|
| @@ -1004,7 +943,7 @@
|
| assert(level >= 0);
|
| new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level)));
|
| q = active_worst_quality +
|
| - vp9_compute_qdelta(cpi, current_q, new_q);
|
| + vp9_compute_qdelta(rc, current_q, new_q);
|
|
|
| *bottom_index = q;
|
| *top_index = q;
|
| @@ -1020,8 +959,7 @@
|
| }
|
|
|
| int vp9_rc_pick_q_and_bounds(const VP9_COMP *cpi,
|
| - int *bottom_index,
|
| - int *top_index) {
|
| + int *bottom_index, int *top_index) {
|
| int q;
|
| if (cpi->pass == 0) {
|
| if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
|
| @@ -1032,14 +970,14 @@
|
| q = rc_pick_q_and_bounds_two_pass(cpi, bottom_index, top_index);
|
| }
|
|
|
| - // JBB : This is realtime mode. In real time mode the first frame
|
| - // should be larger. Q of 0 is disabled because we force tx size to be
|
| + // Q of 0 is disabled because we force tx size to be
|
| // 16x16...
|
| if (cpi->sf.use_nonrd_pick_mode) {
|
| - if (cpi->common.current_video_frame == 0)
|
| - q /= 3;
|
| if (q == 0)
|
| q++;
|
| + if (cpi->sf.force_frame_boost == 1)
|
| + q -= cpi->sf.max_delta_qindex;
|
| +
|
| if (q < *bottom_index)
|
| *bottom_index = q;
|
| else if (q > *top_index)
|
| @@ -1057,28 +995,14 @@
|
| *frame_under_shoot_limit = 0;
|
| *frame_over_shoot_limit = INT_MAX;
|
| } else {
|
| - if (cpi->common.frame_type == KEY_FRAME) {
|
| - *frame_over_shoot_limit = this_frame_target * 9 / 8;
|
| - *frame_under_shoot_limit = this_frame_target * 7 / 8;
|
| - } else {
|
| - if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) {
|
| - *frame_over_shoot_limit = this_frame_target * 9 / 8;
|
| - *frame_under_shoot_limit = this_frame_target * 7 / 8;
|
| - } else {
|
| - // Stron overshoot limit for constrained quality
|
| - if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) {
|
| - *frame_over_shoot_limit = this_frame_target * 11 / 8;
|
| - *frame_under_shoot_limit = this_frame_target * 2 / 8;
|
| - } else {
|
| - *frame_over_shoot_limit = this_frame_target * 11 / 8;
|
| - *frame_under_shoot_limit = this_frame_target * 5 / 8;
|
| - }
|
| - }
|
| - }
|
| + int recode_tolerance =
|
| + (cpi->sf.recode_tolerance * this_frame_target) / 100;
|
|
|
| + *frame_over_shoot_limit = this_frame_target + recode_tolerance;
|
| + *frame_under_shoot_limit = this_frame_target - recode_tolerance;
|
| +
|
| // For very small rate targets where the fractional adjustment
|
| - // (eg * 7/8) may be tiny make sure there is at least a minimum
|
| - // range.
|
| + // may be tiny make sure there is at least a minimum range.
|
| *frame_over_shoot_limit += 200;
|
| *frame_under_shoot_limit -= 200;
|
| if (*frame_under_shoot_limit < 0)
|
| @@ -1103,16 +1027,17 @@
|
|
|
| static void update_alt_ref_frame_stats(VP9_COMP *cpi) {
|
| // this frame refreshes means next frames don't unless specified by user
|
| - cpi->rc.frames_since_golden = 0;
|
| + RATE_CONTROL *const rc = &cpi->rc;
|
| + rc->frames_since_golden = 0;
|
|
|
| #if CONFIG_MULTIPLE_ARF
|
| if (!cpi->multi_arf_enabled)
|
| #endif
|
| // Clear the alternate reference update pending flag.
|
| - cpi->rc.source_alt_ref_pending = 0;
|
| + rc->source_alt_ref_pending = 0;
|
|
|
| // Set the alternate reference frame active flag
|
| - cpi->rc.source_alt_ref_active = 1;
|
| + rc->source_alt_ref_active = 1;
|
| }
|
|
|
| static void update_golden_frame_stats(VP9_COMP *cpi) {
|
| @@ -1141,6 +1066,7 @@
|
|
|
| void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| + const VP9_CONFIG *const oxcf = &cpi->oxcf;
|
| RATE_CONTROL *const rc = &cpi->rc;
|
|
|
| cm->last_frame_type = cm->frame_type;
|
| @@ -1150,7 +1076,7 @@
|
| // Post encode loop adjustment of Q prediction.
|
| vp9_rc_update_rate_correction_factors(
|
| cpi, (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF ||
|
| - cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) ? 2 : 0);
|
| + oxcf->end_usage == USAGE_STREAM_FROM_SERVER) ? 2 : 0);
|
|
|
| // Keep a record of last Q and ambient average Q.
|
| if (cm->frame_type == KEY_FRAME) {
|
| @@ -1159,7 +1085,7 @@
|
| 3 * rc->avg_frame_qindex[KEY_FRAME] + cm->base_qindex, 2);
|
| } else if (!rc->is_src_frame_alt_ref &&
|
| (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) &&
|
| - !(cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) {
|
| + !(cpi->use_svc && oxcf->end_usage == USAGE_STREAM_FROM_SERVER)) {
|
| rc->last_q[2] = cm->base_qindex;
|
| rc->avg_frame_qindex[2] = ROUND_POWER_OF_TWO(
|
| 3 * rc->avg_frame_qindex[2] + cm->base_qindex, 2);
|
| @@ -1205,12 +1131,11 @@
|
|
|
| // Actual bits spent
|
| rc->total_actual_bits += rc->projected_frame_size;
|
| + rc->total_target_bits += (cm->show_frame ? rc->av_per_frame_bandwidth : 0);
|
|
|
| - // Debug stats
|
| - rc->total_target_vs_actual += (rc->this_frame_target -
|
| - rc->projected_frame_size);
|
| + rc->total_target_vs_actual = rc->total_actual_bits - rc->total_target_bits;
|
|
|
| - if (cpi->oxcf.play_alternate && cpi->refresh_alt_ref_frame &&
|
| + if (oxcf->play_alternate && cpi->refresh_alt_ref_frame &&
|
| (cm->frame_type != KEY_FRAME))
|
| // Update the alternate reference frame stats as appropriate.
|
| update_alt_ref_frame_stats(cpi);
|
| @@ -1243,15 +1168,15 @@
|
|
|
| static int calc_pframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) {
|
| static const int af_ratio = 10;
|
| - const RATE_CONTROL *rc = &cpi->rc;
|
| + const RATE_CONTROL *const rc = &cpi->rc;
|
| int target;
|
| #if USE_ALTREF_FOR_ONE_PASS
|
| target = (!rc->is_src_frame_alt_ref &&
|
| (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) ?
|
| - (rc->av_per_frame_bandwidth * cpi->rc.baseline_gf_interval * af_ratio) /
|
| - (cpi->rc.baseline_gf_interval + af_ratio - 1) :
|
| - (rc->av_per_frame_bandwidth * cpi->rc.baseline_gf_interval) /
|
| - (cpi->rc.baseline_gf_interval + af_ratio - 1);
|
| + (rc->av_per_frame_bandwidth * rc->baseline_gf_interval * af_ratio) /
|
| + (rc->baseline_gf_interval + af_ratio - 1) :
|
| + (rc->av_per_frame_bandwidth * rc->baseline_gf_interval) /
|
| + (rc->baseline_gf_interval + af_ratio - 1);
|
| #else
|
| target = rc->av_per_frame_bandwidth;
|
| #endif
|
| @@ -1271,7 +1196,7 @@
|
| int target;
|
| if (!cpi->refresh_alt_ref_frame &&
|
| (cm->current_video_frame == 0 ||
|
| - cm->frame_flags & FRAMEFLAGS_KEY ||
|
| + (cm->frame_flags & FRAMEFLAGS_KEY) ||
|
| rc->frames_to_key == 0 ||
|
| (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) {
|
| cm->frame_type = KEY_FRAME;
|
| @@ -1303,18 +1228,19 @@
|
| static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
|
| const VP9_CONFIG *oxcf = &cpi->oxcf;
|
| const RATE_CONTROL *rc = &cpi->rc;
|
| + const SVC *const svc = &cpi->svc;
|
| const int64_t diff = oxcf->optimal_buffer_level - rc->buffer_level;
|
| const int64_t one_pct_bits = 1 + oxcf->optimal_buffer_level / 100;
|
| int min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4,
|
| FRAME_OVERHEAD_BITS);
|
| int target = rc->av_per_frame_bandwidth;
|
| - if (cpi->svc.number_temporal_layers > 1 &&
|
| - cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
|
| + if (svc->number_temporal_layers > 1 &&
|
| + oxcf->end_usage == USAGE_STREAM_FROM_SERVER) {
|
| // Note that for layers, av_per_frame_bandwidth is the cumulative
|
| // per-frame-bandwidth. For the target size of this frame, use the
|
| // layer average frame size (i.e., non-cumulative per-frame-bw).
|
| - int current_temporal_layer = cpi->svc.temporal_layer_id;
|
| - const LAYER_CONTEXT *lc = &cpi->svc.layer_context[current_temporal_layer];
|
| + int current_temporal_layer = svc->temporal_layer_id;
|
| + const LAYER_CONTEXT *lc = &svc->layer_context[current_temporal_layer];
|
| target = lc->avg_frame_size;
|
| min_frame_target = MAX(lc->avg_frame_size >> 4, FRAME_OVERHEAD_BITS);
|
| }
|
| @@ -1351,13 +1277,14 @@
|
|
|
| void vp9_rc_get_svc_params(VP9_COMP *cpi) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| - int target = cpi->rc.av_per_frame_bandwidth;
|
| + RATE_CONTROL *const rc = &cpi->rc;
|
| + int target = rc->av_per_frame_bandwidth;
|
| if ((cm->current_video_frame == 0) ||
|
| (cm->frame_flags & FRAMEFLAGS_KEY) ||
|
| - (cpi->oxcf.auto_key && (cpi->rc.frames_since_key %
|
| + (cpi->oxcf.auto_key && (rc->frames_since_key %
|
| cpi->key_frame_frequency == 0))) {
|
| cm->frame_type = KEY_FRAME;
|
| - cpi->rc.source_alt_ref_active = 0;
|
| + rc->source_alt_ref_active = 0;
|
| if (cpi->pass == 0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
|
| target = calc_iframe_target_size_one_pass_cbr(cpi);
|
| }
|
| @@ -1368,8 +1295,8 @@
|
| }
|
| }
|
| vp9_rc_set_frame_target(cpi, target);
|
| - cpi->rc.frames_till_gf_update_due = INT_MAX;
|
| - cpi->rc.baseline_gf_interval = INT_MAX;
|
| + rc->frames_till_gf_update_due = INT_MAX;
|
| + rc->baseline_gf_interval = INT_MAX;
|
| }
|
|
|
| void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) {
|
| @@ -1377,7 +1304,7 @@
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| int target;
|
| if ((cm->current_video_frame == 0 ||
|
| - cm->frame_flags & FRAMEFLAGS_KEY ||
|
| + (cm->frame_flags & FRAMEFLAGS_KEY) ||
|
| rc->frames_to_key == 0 ||
|
| (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) {
|
| cm->frame_type = KEY_FRAME;
|
| @@ -1396,3 +1323,46 @@
|
| rc->frames_till_gf_update_due = INT_MAX;
|
| rc->baseline_gf_interval = INT_MAX;
|
| }
|
| +
|
| +int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget) {
|
| + int start_index = rc->worst_quality;
|
| + int target_index = rc->worst_quality;
|
| + int i;
|
| +
|
| + // Convert the average q value to an index.
|
| + for (i = rc->best_quality; i < rc->worst_quality; ++i) {
|
| + start_index = i;
|
| + if (vp9_convert_qindex_to_q(i) >= qstart)
|
| + break;
|
| + }
|
| +
|
| + // Convert the q target to an index
|
| + for (i = rc->best_quality; i < rc->worst_quality; ++i) {
|
| + target_index = i;
|
| + if (vp9_convert_qindex_to_q(i) >= qtarget)
|
| + break;
|
| + }
|
| +
|
| + return target_index - start_index;
|
| +}
|
| +
|
| +int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type,
|
| + int qindex, double rate_target_ratio) {
|
| + int target_index = rc->worst_quality;
|
| + int i;
|
| +
|
| + // Look up the current projected bits per block for the base index
|
| + const int base_bits_per_mb = vp9_rc_bits_per_mb(frame_type, qindex, 1.0);
|
| +
|
| + // Find the target bits per mb based on the base value and given ratio.
|
| + const int target_bits_per_mb = (int)(rate_target_ratio * base_bits_per_mb);
|
| +
|
| + // Convert the q target to an index
|
| + for (i = rc->best_quality; i < rc->worst_quality; ++i) {
|
| + target_index = i;
|
| + if (vp9_rc_bits_per_mb(frame_type, i, 1.0) <= target_bits_per_mb )
|
| + break;
|
| + }
|
| +
|
| + return target_index - qindex;
|
| +}
|
|
|