summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorRavi Chaudhary <ravi.chaudhary@ittiam.com>2019-05-24 11:27:06 +0530
committerRavi Chaudhary <ravi.chaudhary@ittiam.com>2019-07-01 18:08:26 +0530
commit16de4d7366f1f084eb969385016e1e950df9180f (patch)
tree7d05085a82f693e8402ebe28232b52df197e607c /vp9/encoder
parent01cac9f374345c3bba337ef5e63fd2693473bca5 (diff)
downloadlibvpx-16de4d7366f1f084eb969385016e1e950df9180f.tar
libvpx-16de4d7366f1f084eb969385016e1e950df9180f.tar.gz
libvpx-16de4d7366f1f084eb969385016e1e950df9180f.tar.bz2
libvpx-16de4d7366f1f084eb969385016e1e950df9180f.zip
Adjust the quality of boosted frames
As the boosted frames, early in key frame interval, are used as reference by many subsequent boosted frames, boosted frames that are closer to the reference key frame should be allocated with more target bits than the rest. Similarly, the active best quality should be lower for boosted frames early in the key interval and vice versa. Hence, the bits allocation and active best quality are varied based on their temporal position in the key frame interval. Change-Id: I1362248560d074b9e209657a23ae73dda0b01d52
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_firstpass.c44
-rw-r--r--vp9/encoder/vp9_ratectrl.c26
-rw-r--r--vp9/encoder/vp9_ratectrl.h2
3 files changed, 49 insertions, 23 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index e0acf563b..17d0d042c 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2060,8 +2060,19 @@ static int64_t calculate_total_gf_group_bits(VP9_COMP *cpi,
// Calculate the bits to be allocated to the group as a whole.
if ((twopass->kf_group_bits > 0) && (twopass->kf_group_error_left > 0.0)) {
+ int key_frame_interval = rc->frames_since_key + rc->frames_to_key;
+ int distance_from_next_key_frame =
+ rc->frames_to_key -
+ (rc->baseline_gf_interval + rc->source_alt_ref_pending);
+ int max_gf_bits_bias = rc->avg_frame_bandwidth;
+ double gf_interval_bias_bits_normalize_factor =
+ (double)rc->baseline_gf_interval / 16;
total_group_bits = (int64_t)(twopass->kf_group_bits *
(gf_group_err / twopass->kf_group_error_left));
+ // TODO(ravi): Experiment with different values of max_gf_bits_bias
+ total_group_bits +=
+ (int64_t)((double)distance_from_next_key_frame / key_frame_interval *
+ max_gf_bits_bias * gf_interval_bias_bits_normalize_factor);
} else {
total_group_bits = 0;
}
@@ -2651,13 +2662,27 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
#define LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR 0.2
rc->arf_active_best_quality_adjustment_factor = 1.0;
- if (rc->source_alt_ref_pending && !is_lossless_requested(&cpi->oxcf) &&
- rc->frames_to_key <= rc->arf_active_best_quality_adjustment_window) {
- rc->arf_active_best_quality_adjustment_factor =
- LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR +
- (1.0 - LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR) *
- (rc->frames_to_key - i) /
- VPXMAX(1, (rc->arf_active_best_quality_adjustment_window - i));
+ rc->arf_increase_active_best_quality = 0;
+
+ if (!is_lossless_requested(&cpi->oxcf)) {
+ if (rc->frames_since_key >= rc->frames_to_key) {
+ // Increase the active best quality in the second half of key frame
+ // interval.
+ rc->arf_active_best_quality_adjustment_factor =
+ LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR +
+ (1.0 - LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR) *
+ (rc->frames_to_key - i) /
+ (VPXMAX(1, ((rc->frames_to_key + rc->frames_since_key) / 2 - i)));
+ rc->arf_increase_active_best_quality = 1;
+ } else if ((rc->frames_to_key - i) > 0) {
+ // Reduce the active best quality in the first half of key frame interval.
+ rc->arf_active_best_quality_adjustment_factor =
+ LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR +
+ (1.0 - LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR) *
+ (rc->frames_since_key + i) /
+ (VPXMAX(1, (rc->frames_to_key + rc->frames_since_key) / 2 + i));
+ rc->arf_increase_active_best_quality = -1;
+ }
}
#ifdef AGGRESSIVE_VBR
@@ -3227,11 +3252,6 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Default to normal-sized frame on keyframes.
cpi->rc.next_frame_size_selector = UNSCALED;
}
-#define ARF_ACTIVE_BEST_QUALITY_ADJUSTMENT_WINDOW_SIZE 64
- // TODO(ravi.chaudhary@ittiam.com): Experiment without the below min
- // condition. This might be helpful for small key frame intervals.
- rc->arf_active_best_quality_adjustment_window =
- VPXMIN(ARF_ACTIVE_BEST_QUALITY_ADJUSTMENT_WINDOW_SIZE, rc->frames_to_key);
}
static int is_skippable_frame(const VP9_COMP *cpi) {
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 6745b0adf..fe26db5d5 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -436,7 +436,7 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) {
rc->use_post_encode_drop = 0;
rc->ext_use_post_encode_drop = 0;
rc->arf_active_best_quality_adjustment_factor = 1.0;
-
+ rc->arf_increase_active_best_quality = 0;
rc->preserve_arf_as_gld = 0;
rc->preserve_next_arf_as_gld = 0;
rc->show_arf_as_gld = 0;
@@ -1420,8 +1420,8 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index,
int active_worst_quality = cpi->twopass.active_worst_quality;
int q;
int *inter_minq;
- int arf_active_best_quality_adjustment, arf_active_best_quality_max;
- int *arfgf_high_motion_minq;
+ int arf_active_best_quality_hl;
+ int *arfgf_high_motion_minq, *arfgf_low_motion_minq;
const int boost_frame =
!rc->is_src_frame_alt_ref &&
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame);
@@ -1448,14 +1448,20 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index,
if (q < cq_level) q = cq_level;
}
active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
+ arf_active_best_quality_hl = active_best_quality;
- ASSIGN_MINQ_TABLE(cm->bit_depth, arfgf_high_motion_minq);
- arf_active_best_quality_max = arfgf_high_motion_minq[q];
- arf_active_best_quality_adjustment =
- arf_active_best_quality_max - active_best_quality;
- active_best_quality = arf_active_best_quality_max -
- (int)(arf_active_best_quality_adjustment *
- rc->arf_active_best_quality_adjustment_factor);
+ if (rc->arf_increase_active_best_quality == 1) {
+ ASSIGN_MINQ_TABLE(cm->bit_depth, arfgf_high_motion_minq);
+ arf_active_best_quality_hl = arfgf_high_motion_minq[q];
+ } else if (rc->arf_increase_active_best_quality == -1) {
+ ASSIGN_MINQ_TABLE(cm->bit_depth, arfgf_low_motion_minq);
+ arf_active_best_quality_hl = arfgf_low_motion_minq[q];
+ }
+ active_best_quality =
+ (int)((double)active_best_quality *
+ rc->arf_active_best_quality_adjustment_factor +
+ (double)arf_active_best_quality_hl *
+ (1.0 - rc->arf_active_best_quality_adjustment_factor));
// Modify best quality for second level arfs. For mode VPX_Q this
// becomes the baseline frame q.
diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h
index 09d69e4d4..1100ce734 100644
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -198,7 +198,7 @@ typedef struct {
int damped_adjustment[RATE_FACTOR_LEVELS];
double arf_active_best_quality_adjustment_factor;
- int arf_active_best_quality_adjustment_window;
+ int arf_increase_active_best_quality;
int preserve_arf_as_gld;
int preserve_next_arf_as_gld;