shithub: libvpx

Download patch

ref: 9bfdf4a9d0c35706012fdcf7657d57c68bca0eb8
parent: 90271b22016b89a115206a38ab4790a76cce3553
author: Angie Chiang <angiebird@google.com>
date: Fri Oct 16 14:36:09 EDT 2020

Add ref frame info to vpx_rc_encodeframe_info_t

Bug: webm:1707

Change-Id: I2ff9e54a9c8ae535628c1c471a2d078652f49a31

--- a/test/vp9_ext_ratectrl_test.cc
+++ b/test/vp9_ext_ratectrl_test.cc
@@ -72,10 +72,24 @@
 
   if (encode_frame_info->coding_index == 0) {
     EXPECT_EQ(encode_frame_info->frame_type, 0 /*kFrameTypeKey*/);
+    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0],
+              0);  // kRefFrameTypeLast
+    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1],
+              0);  // kRefFrameTypePast
+    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2],
+              0);  // kRefFrameTypeFuture
   }
 
   if (encode_frame_info->coding_index == 1) {
     EXPECT_EQ(encode_frame_info->frame_type, 2 /*kFrameTypeAltRef*/);
+    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0],
+              1);  // kRefFrameTypeLast
+    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1],
+              0);  // kRefFrameTypePast
+    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2],
+              0);  // kRefFrameTypeFuture
+    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[0],
+              0);  // kRefFrameTypeLast
   }
 
   if (encode_frame_info->coding_index >= 2 &&
@@ -85,6 +99,18 @@
 
   if (encode_frame_info->coding_index == 5) {
     EXPECT_EQ(encode_frame_info->frame_type, 3 /*kFrameTypeOverlay*/);
+    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0],
+              1);  // kRefFrameTypeLast
+    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1],
+              1);  // kRefFrameTypePast
+    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2],
+              1);  // kRefFrameTypeFuture
+    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[0],
+              4);  // kRefFrameTypeLast
+    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[1],
+              0);  // kRefFrameTypePast
+    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[2],
+              1);  // kRefFrameTypeFuture
   }
   if (encode_frame_info->coding_index == kLosslessCodingIndex) {
     // We should get sse == 0 at rc_update_encodeframe_result()
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -75,12 +75,10 @@
 
   // TODO(angiebird): Set frame_index/frame_coding_index on the decoder side
   // properly.
-  int frame_index;  // Display order in the video, it's equivalent to the
-                    // show_idx defined in EncodeFrameInfo.
-#if CONFIG_RATE_CTRL
+  int frame_index;         // Display order in the video, it's equivalent to the
+                           // show_idx defined in EncodeFrameInfo.
   int frame_coding_index;  // The coding order (starting from zero) of this
                            // frame.
-#endif                     // CONFIG_RATE_CTRL
   vpx_codec_frame_buffer_t raw_frame_buffer;
   YV12_BUFFER_CONFIG buf;
 } RefCntBuffer;
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -4205,6 +4205,27 @@
   return 1;
 }
 
+static int get_ref_frame_flags(const VP9_COMP *cpi) {
+  const int *const map = cpi->common.ref_frame_map;
+  const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
+  const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
+  const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
+  int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
+
+  if (gold_is_last) flags &= ~VP9_GOLD_FLAG;
+
+  if (cpi->rc.frames_till_gf_update_due == INT_MAX &&
+      (cpi->svc.number_temporal_layers == 1 &&
+       cpi->svc.number_spatial_layers == 1))
+    flags &= ~VP9_GOLD_FLAG;
+
+  if (alt_is_last) flags &= ~VP9_ALT_FLAG;
+
+  if (gold_is_alt) flags &= ~VP9_ALT_FLAG;
+
+  return flags;
+}
+
 #if !CONFIG_REALTIME_ONLY
 #define MAX_QSTEP_ADJ 4
 static int get_qstep_adj(int rate_excess, int rate_limit) {
@@ -4481,9 +4502,14 @@
     if (cpi->ext_ratectrl.ready) {
       const GF_GROUP *gf_group = &cpi->twopass.gf_group;
       vpx_rc_encodeframe_decision_t encode_frame_decision;
+      FRAME_UPDATE_TYPE update_type = gf_group->update_type[gf_group->index];
+      const int ref_frame_flags = get_ref_frame_flags(cpi);
+      RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES];
+      get_ref_frame_bufs(cpi, ref_frame_bufs);
       vp9_extrc_get_encodeframe_decision(
-          &cpi->ext_ratectrl, gf_group, cm->current_video_frame,
-          cm->current_frame_coding_index, &encode_frame_decision);
+          &cpi->ext_ratectrl, cm->current_video_frame,
+          cm->current_frame_coding_index, update_type, ref_frame_bufs,
+          ref_frame_flags, &encode_frame_decision);
       q = encode_frame_decision.q_index;
     }
 
@@ -4772,27 +4798,6 @@
 }
 #endif  // !CONFIG_REALTIME_ONLY
 
-static int get_ref_frame_flags(const VP9_COMP *cpi) {
-  const int *const map = cpi->common.ref_frame_map;
-  const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
-  const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
-  const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
-  int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
-
-  if (gold_is_last) flags &= ~VP9_GOLD_FLAG;
-
-  if (cpi->rc.frames_till_gf_update_due == INT_MAX &&
-      (cpi->svc.number_temporal_layers == 1 &&
-       cpi->svc.number_spatial_layers == 1))
-    flags &= ~VP9_GOLD_FLAG;
-
-  if (alt_is_last) flags &= ~VP9_ALT_FLAG;
-
-  if (gold_is_alt) flags &= ~VP9_ALT_FLAG;
-
-  return flags;
-}
-
 static void set_ext_overrides(VP9_COMP *cpi) {
   // Overrides the defaults with the externally supplied values with
   // vp9_update_reference() and vp9_update_entropy() calls
@@ -5097,9 +5102,7 @@
     const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
     ref_buffer->frame_index =
         cm->current_video_frame + gf_group->arf_src_offset[gf_group->index];
-#if CONFIG_RATE_CTRL
     ref_buffer->frame_coding_index = cm->current_frame_coding_index;
-#endif  // CONFIG_RATE_CTRL
   }
 }
 
@@ -7391,6 +7394,30 @@
 #endif  // CONFIG_NON_GREEDY_MV
 }
 
+void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags,
+                            RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES],
+                            int *ref_frame_coding_indexes,
+                            int *ref_frame_valid_list) {
+  if (update_type != KF_UPDATE) {
+    const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG,
+                                                                 VP9_GOLD_FLAG,
+                                                                 VP9_ALT_FLAG };
+    int i;
+    for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) {
+      assert(ref_frame_bufs[i] != NULL);
+      ref_frame_coding_indexes[i] = ref_frame_bufs[i]->frame_coding_index;
+      ref_frame_valid_list[i] = (ref_frame_flags & inter_ref_flags[i]) != 0;
+    }
+  } else {
+    // No reference frame is available when this is a key frame.
+    int i;
+    for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) {
+      ref_frame_coding_indexes[i] = -1;
+      ref_frame_valid_list[i] = 0;
+    }
+  }
+}
+
 #if !CONFIG_REALTIME_ONLY
 #if CONFIG_RATE_CTRL
 static void copy_frame_counts(const FRAME_COUNTS *input_counts,
@@ -7538,6 +7565,7 @@
   }
 }
 #endif  // CONFIG_RATE_CTRL
+
 static void update_encode_frame_result(
     int ref_frame_flags, FRAME_UPDATE_TYPE update_type,
     const YV12_BUFFER_CONFIG *source_frame, const RefCntBuffer *coded_frame_buf,
@@ -7560,26 +7588,10 @@
 #endif  // CONFIG_VP9_HIGHBITDEPTH
   encode_frame_result->frame_coding_index = coded_frame_buf->frame_coding_index;
 
-  if (update_type != KF_UPDATE) {
-    const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG,
-                                                                 VP9_GOLD_FLAG,
-                                                                 VP9_ALT_FLAG };
-    int i;
-    for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) {
-      assert(ref_frame_bufs[i] != NULL);
-      encode_frame_result->ref_frame_coding_indexes[i] =
-          ref_frame_bufs[i]->frame_coding_index;
-      encode_frame_result->ref_frame_valid_list[i] =
-          (ref_frame_flags & inter_ref_flags[i]) != 0;
-    }
-  } else {
-    // No reference frame is available when this is a key frame.
-    int i;
-    for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) {
-      encode_frame_result->ref_frame_coding_indexes[i] = -1;
-      encode_frame_result->ref_frame_valid_list[i] = 0;
-    }
-  }
+  vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs,
+                         encode_frame_result->ref_frame_coding_indexes,
+                         encode_frame_result->ref_frame_valid_list);
+
   encode_frame_result->psnr = psnr.psnr[0];
   encode_frame_result->sse = psnr.sse[0];
   copy_frame_counts(counts, &encode_frame_result->frame_counts);
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -1268,6 +1268,11 @@
 
 void vp9_update_reference_frames(VP9_COMP *cpi);
 
+void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags,
+                            RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES],
+                            int *ref_frame_coding_indexes,
+                            int *ref_frame_valid_list);
+
 void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv);
 
 YV12_BUFFER_CONFIG *vp9_svc_twostage_scale(
--- a/vp9/encoder/vp9_ext_ratectrl.c
+++ b/vp9/encoder/vp9_ext_ratectrl.c
@@ -9,6 +9,7 @@
  */
 
 #include "vp9/encoder/vp9_ext_ratectrl.h"
+#include "vp9/encoder/vp9_encoder.h"
 #include "vp9/common/vp9_common.h"
 #include "vpx_dsp/psnr.h"
 
@@ -102,14 +103,20 @@
 }
 
 void vp9_extrc_get_encodeframe_decision(
-    EXT_RATECTRL *ext_ratectrl, const GF_GROUP *gf_group, int show_index,
-    int coding_index, vpx_rc_encodeframe_decision_t *encode_frame_decision) {
+    EXT_RATECTRL *ext_ratectrl, int show_index, int coding_index,
+    FRAME_UPDATE_TYPE update_type,
+    RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int ref_frame_flags,
+    vpx_rc_encodeframe_decision_t *encode_frame_decision) {
   if (ext_ratectrl->ready) {
-    FRAME_UPDATE_TYPE update_type = gf_group->update_type[gf_group->index];
     vpx_rc_encodeframe_info_t encode_frame_info;
     encode_frame_info.show_index = show_index;
     encode_frame_info.coding_index = coding_index;
     encode_frame_info.frame_type = extrc_get_frame_type(update_type);
+
+    vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs,
+                           encode_frame_info.ref_frame_coding_indexes,
+                           encode_frame_info.ref_frame_valid_list);
+
     ext_ratectrl->funcs.get_encodeframe_decision(
         ext_ratectrl->model, &encode_frame_info, encode_frame_decision);
   }
--- a/vp9/encoder/vp9_ext_ratectrl.h
+++ b/vp9/encoder/vp9_ext_ratectrl.h
@@ -33,8 +33,10 @@
                                     const FIRST_PASS_INFO *first_pass_info);
 
 void vp9_extrc_get_encodeframe_decision(
-    EXT_RATECTRL *ext_ratectrl, const GF_GROUP *gf_group, int show_index,
-    int coding_index, vpx_rc_encodeframe_decision_t *encode_frame_decision);
+    EXT_RATECTRL *ext_ratectrl, int show_index, int coding_index,
+    FRAME_UPDATE_TYPE update_type,
+    RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int ref_frame_flags,
+    vpx_rc_encodeframe_decision_t *encode_frame_decision);
 
 void vp9_extrc_update_encodeframe_result(EXT_RATECTRL *ext_ratectrl,
                                          int64_t bit_count,
--- a/vpx/vpx_ext_ratectrl.h
+++ b/vpx/vpx_ext_ratectrl.h
@@ -31,6 +31,8 @@
   int frame_type;
   int show_index;
   int coding_index;
+  int ref_frame_coding_indexes[3];
+  int ref_frame_valid_list[3];
 } vpx_rc_encodeframe_info_t;
 
 typedef struct vpx_rc_encodeframe_result {