]> granicus.if.org Git - libvpx/commitdiff
Use previous ARF as GOLDEN frame for the next GOP
authorDeepa K G <deepa.kg@ittiam.com>
Tue, 9 Apr 2019 12:25:36 +0000 (17:55 +0530)
committerDeepa K G <deepa.kg@ittiam.com>
Tue, 11 Jun 2019 13:36:00 +0000 (19:06 +0530)
This patch uses ARF itself as the GOLDEN frame for the
next gf group instead of replacing it with the overlay
frame. By doing so, bits consumed by the overlay frame
will be reduced.

Change-Id: I909ceaa6d501c267d315614075913d45ad426c15

vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_firstpass.c
vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_ratectrl.h

index 900d92f851ecaac788f3a12564b5a414aca5c532..260058827f124f95e50acc84c85de0514d7145dd 100644 (file)
@@ -3063,8 +3063,12 @@ static void update_ref_frames(VP9_COMP *cpi) {
   BufferPool *const pool = cm->buffer_pool;
   GF_GROUP *const gf_group = &cpi->twopass.gf_group;
 
-  // Pop ARF.
-  if (cm->show_existing_frame) {
+  if (cpi->rc.show_arf_as_gld) {
+    int tmp = cpi->alt_fb_idx;
+    cpi->alt_fb_idx = cpi->gld_fb_idx;
+    cpi->gld_fb_idx = tmp;
+  } else if (cm->show_existing_frame) {
+    // Pop ARF.
     cpi->lst_fb_idx = cpi->alt_fb_idx;
     cpi->alt_fb_idx =
         stack_pop(gf_group->arf_index_stack, gf_group->stack_size);
index 01121dea6eef2d3eea8c31a90b7a039b79963b8c..e0acf563b8393227ec31323c107f1230f93cef43 100644 (file)
@@ -2455,6 +2455,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   int gf_arf_bits;
   const int is_key_frame = frame_is_intra_only(cm);
   const int arf_active_or_kf = is_key_frame || rc->source_alt_ref_active;
+  int is_alt_ref_flash = 0;
 
   double gop_intra_factor = 1.0;
   int gop_frames;
@@ -2678,6 +2679,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   // Reset the file position.
   reset_fpf_position(twopass, start_pos);
 
+  if (rc->source_alt_ref_pending)
+    is_alt_ref_flash = detect_flash(twopass, rc->baseline_gf_interval);
+
   // Calculate the bits to be allocated to the gf/arf group as a whole
   gf_group_bits = calculate_total_gf_group_bits(cpi, gf_group_err);
 
@@ -2755,6 +2759,12 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
   twopass->rolling_arf_group_target_bits = 0;
   twopass->rolling_arf_group_actual_bits = 0;
 #endif
+  rc->preserve_arf_as_gld = rc->preserve_next_arf_as_gld;
+  rc->preserve_next_arf_as_gld = 0;
+  // If alt ref frame is flash do not set preserve_arf_as_gld
+  if (!is_lossless_requested(&cpi->oxcf) && !cpi->use_svc &&
+      cpi->oxcf.aq_mode == NO_AQ && cpi->multi_layer_arf && !is_alt_ref_flash)
+    rc->preserve_next_arf_as_gld = 1;
 }
 
 // Intra / Inter threshold very low
index e45030ab88bbe5ab05ebb582b8c4684e68c186ad..a8f75b75014a18099bf170c40737a597a7857354 100644 (file)
@@ -436,6 +436,10 @@ 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->preserve_arf_as_gld = 0;
+  rc->preserve_next_arf_as_gld = 0;
+  rc->show_arf_as_gld = 0;
 }
 
 static int check_buffer_above_thresh(VP9_COMP *cpi, int drop_mark) {
@@ -1574,6 +1578,7 @@ void vp9_configure_buffer_updates(VP9_COMP *cpi, int gf_group_index) {
 
   cpi->rc.is_src_frame_alt_ref = 0;
   cm->show_existing_frame = 0;
+  cpi->rc.show_arf_as_gld = 0;
   switch (twopass->gf_group.update_type[gf_group_index]) {
     case KF_UPDATE:
       cpi->refresh_last_frame = 1;
@@ -1595,6 +1600,12 @@ void vp9_configure_buffer_updates(VP9_COMP *cpi, int gf_group_index) {
       cpi->refresh_golden_frame = 1;
       cpi->refresh_alt_ref_frame = 0;
       cpi->rc.is_src_frame_alt_ref = 1;
+      if (cpi->rc.preserve_arf_as_gld) {
+        cpi->rc.show_arf_as_gld = 1;
+        cpi->refresh_golden_frame = 0;
+        cm->show_existing_frame = 1;
+        cm->refresh_frame_context = 0;
+      }
       break;
     case MID_OVERLAY_UPDATE:
       cpi->refresh_last_frame = 1;
@@ -1716,6 +1727,15 @@ static void update_golden_frame_stats(VP9_COMP *cpi) {
     if (rc->frames_till_gf_update_due > 0) rc->frames_till_gf_update_due--;
 
     rc->frames_since_golden++;
+
+    if (rc->show_arf_as_gld) {
+      rc->frames_since_golden = 0;
+      // If we are not using alt ref in the up and coming group clear the arf
+      // active flag. In multi arf group case, if the index is not 0 then
+      // we are overlaying a mid group arf so should not reset the flag.
+      if (!rc->source_alt_ref_pending && (cpi->twopass.gf_group.index == 0))
+        rc->source_alt_ref_active = 0;
+    }
   }
 }
 
index 2c2048edc57809806c52ed9c4417480d1556b1e8..09d69e4d4e16802de10d80bb7e56b3e89a3781b9 100644 (file)
@@ -199,6 +199,10 @@ typedef struct {
   int damped_adjustment[RATE_FACTOR_LEVELS];
   double arf_active_best_quality_adjustment_factor;
   int arf_active_best_quality_adjustment_window;
+
+  int preserve_arf_as_gld;
+  int preserve_next_arf_as_gld;
+  int show_arf_as_gld;
 } RATE_CONTROL;
 
 struct VP9_COMP;