summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorpaulwilkins <paulwilkins@google.com>2017-08-17 14:13:29 +0100
committerpaulwilkins <paulwilkins@google.com>2017-10-10 10:41:35 +0100
commit06d231c9fa8db062a16834f5d767ecd0912a5e1d (patch)
tree35a284f707eec6b7e53817c21e4f6d8ca6ba2f6e /vp9/encoder
parent741bd6df4fbbd013b0a8d2f62c555e0314a9801b (diff)
downloadlibvpx-06d231c9fa8db062a16834f5d767ecd0912a5e1d.tar
libvpx-06d231c9fa8db062a16834f5d767ecd0912a5e1d.tar.gz
libvpx-06d231c9fa8db062a16834f5d767ecd0912a5e1d.tar.bz2
libvpx-06d231c9fa8db062a16834f5d767ecd0912a5e1d.zip
Further Corpus VBR change.
Change to the bit allocation within a GF/ARF group. Normal VBR and CQ mode allocate bits to a GF/ARF group based of the mean complexity score of the frames in that group but then share bits evenly between the "normal" frames in that group regardless of the individual frame complexity scores (with the exception of the middle and last frames). This patch alters the behavior for the experimental "Corpus VBR" mode such that the allocation is always based on the individual complexity scores. Change-Id: I5045a143eadeb452302886cc5ccffd0906b75708
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_firstpass.c59
1 files changed, 48 insertions, 11 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index a4c6bb0ae..9d9779f7b 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2185,6 +2185,28 @@ static void get_arf_buffer_indices(unsigned char *arf_buffer_indices) {
arf_buffer_indices[1] = ARF_SLOT2;
}
+#ifdef CORPUS_VBR_EXPERIMENT
+// Calculates the total normalized group complexity score for a given number
+// of frames starting at the current position in the stats file.
+static double calculate_group_score(VP9_COMP *cpi, double av_score,
+ int frame_count) {
+ VP9EncoderConfig *const oxcf = &cpi->oxcf;
+ TWO_PASS *const twopass = &cpi->twopass;
+ const FIRSTPASS_STATS *s = twopass->stats_in;
+ double score_total = 0.0;
+ int i = 0;
+
+ while ((i < frame_count) && (s < twopass->stats_in_end)) {
+ score_total += calculate_norm_frame_score(cpi, twopass, oxcf, s, av_score);
+ ++s;
+ ++i;
+ }
+ assert(i == frame_count);
+
+ return score_total;
+}
+#endif
+
static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
int gf_arf_bits) {
RATE_CONTROL *const rc = &cpi->rc;
@@ -2205,8 +2227,13 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
is_two_pass_svc(cpi) && cpi->svc.number_temporal_layers > 1;
int normal_frames;
int normal_frame_bits;
- int last_frame_bits;
- int last_frame_reduction;
+ int last_frame_reduction = 0;
+
+#ifdef CORPUS_VBR_EXPERIMENT
+ double av_score = get_distribution_av_err(twopass);
+ double tot_norm_frame_score;
+ double this_frame_score;
+#endif
// Only encode alt reference frame in temporal base layer.
if (has_temporal_layers) alt_frame_index = cpi->svc.number_temporal_layers;
@@ -2279,17 +2306,17 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
normal_frames = (rc->baseline_gf_interval - rc->source_alt_ref_pending);
+#ifndef CORPUS_VBR_EXPERIMENT
// The last frame in the group is used less as a predictor so reduce
// its allocation a little.
if (normal_frames > 1) {
normal_frame_bits = (int)(total_group_bits / normal_frames);
- last_frame_reduction = normal_frame_bits / 16;
- last_frame_bits = normal_frame_bits - last_frame_reduction;
} else {
normal_frame_bits = (int)total_group_bits;
- last_frame_bits = normal_frame_bits;
- last_frame_reduction = 0;
}
+#else
+ tot_norm_frame_score = calculate_group_score(cpi, av_score, normal_frames);
+#endif
// Allocate bits to the other frames in the group.
for (i = 0; i < normal_frames; ++i) {
@@ -2300,11 +2327,18 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
++frame_index;
}
- target_frame_size = (i == (normal_frames - 1))
- ? last_frame_bits
- : (frame_index == mid_frame_idx)
- ? normal_frame_bits + last_frame_reduction
- : normal_frame_bits;
+#ifdef CORPUS_VBR_EXPERIMENT
+ this_frame_score = calculate_norm_frame_score(cpi, twopass, &cpi->oxcf,
+ &frame_stats, av_score);
+ normal_frame_bits = (int)((double)total_group_bits *
+ (this_frame_score / tot_norm_frame_score));
+#endif
+
+ target_frame_size = normal_frame_bits;
+ if ((i == (normal_frames - 1)) && (i >= 1)) {
+ last_frame_reduction = normal_frame_bits / 16;
+ target_frame_size -= last_frame_reduction;
+ }
if (rc->source_alt_ref_pending && cpi->multi_arf_enabled) {
mid_boost_bits += (target_frame_size >> 4);
@@ -2325,6 +2359,9 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
++frame_index;
}
+ // Add in some extra bits for the middle frame in the group.
+ gf_group->bit_allocation[mid_frame_idx] += last_frame_reduction;
+
// Note:
// We need to configure the frame at the end of the sequence + 1 that will be
// the start frame for the next group. Otherwise prior to the call to