shithub: libvpx

Download patch

ref: ee482c87c749e727915e8c5cb7d6e0b414286851
parent: 13aad8bb6404d56138c16886939cf50c63850651
parent: a207a0f6b9af8e05e4379d5a8f29f549d3b32c61
author: Angie Chiang <angiebird@google.com>
date: Wed Oct 21 17:26:34 EDT 2020

Merge changes I27932c41,I2ff9e54a,I4ebed472

* changes:
  Small changes of vp9_ext_ratectrl_test.cc
  Add ref frame info to vpx_rc_encodeframe_info_t
  Add vpx_rc_status_t

--- a/test/vp9_ext_ratectrl_test.cc
+++ b/test/vp9_ext_ratectrl_test.cc
@@ -8,6 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include <new>
+
 #include "test/codec_factory.h"
 #include "test/encode_test_driver.h"
 #include "test/util.h"
@@ -18,7 +20,7 @@
 namespace {
 
 constexpr int kModelMagicNumber = 51396;
-constexpr unsigned int PrivMagicNumber = 5566UL;
+constexpr unsigned int PrivMagicNumber = 5566;
 constexpr int kFrameNum = 5;
 constexpr int kLosslessCodingIndex = 2;
 
@@ -27,13 +29,14 @@
   int coding_index;
 };
 
-int rc_create_model(void *priv, const vpx_rc_config_t *ratectrl_config,
-                    vpx_rc_model_t *rate_ctrl_model_pt) {
+vpx_rc_status_t rc_create_model(void *priv,
+                                const vpx_rc_config_t *ratectrl_config,
+                                vpx_rc_model_t *rate_ctrl_model_pt) {
   ToyRateCtrl *toy_rate_ctrl = new (std::nothrow) ToyRateCtrl;
   EXPECT_NE(toy_rate_ctrl, nullptr);
   toy_rate_ctrl->magic_number = kModelMagicNumber;
   toy_rate_ctrl->coding_index = -1;
-  *rate_ctrl_model_pt = (vpx_rc_model_t)toy_rate_ctrl;
+  *rate_ctrl_model_pt = toy_rate_ctrl;
   EXPECT_EQ(priv, reinterpret_cast<void *>(PrivMagicNumber));
   EXPECT_EQ(ratectrl_config->frame_width, 352);
   EXPECT_EQ(ratectrl_config->frame_height, 288);
@@ -41,11 +44,12 @@
   EXPECT_EQ(ratectrl_config->target_bitrate_kbps, 24000);
   EXPECT_EQ(ratectrl_config->frame_rate_num, 30);
   EXPECT_EQ(ratectrl_config->frame_rate_den, 1);
-  return 0;
+  return vpx_rc_ok;
 }
 
-int rc_send_firstpass_stats(vpx_rc_model_t rate_ctrl_model,
-                            const vpx_rc_firstpass_stats_t *first_pass_stats) {
+vpx_rc_status_t rc_send_firstpass_stats(
+    vpx_rc_model_t rate_ctrl_model,
+    const vpx_rc_firstpass_stats_t *first_pass_stats) {
   const ToyRateCtrl *toy_rate_ctrl =
       static_cast<ToyRateCtrl *>(rate_ctrl_model);
   EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);
@@ -53,10 +57,10 @@
   for (int i = 0; i < first_pass_stats->num_frames; ++i) {
     EXPECT_DOUBLE_EQ(first_pass_stats->frame_stats[i].frame, i);
   }
-  return 0;
+  return vpx_rc_ok;
 }
 
-int rc_get_encodeframe_decision(
+vpx_rc_status_t rc_get_encodeframe_decision(
     vpx_rc_model_t rate_ctrl_model,
     const vpx_rc_encodeframe_info_t *encode_frame_info,
     vpx_rc_encodeframe_decision_t *frame_decision) {
@@ -70,10 +74,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 &&
@@ -83,6 +101,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()
@@ -90,10 +120,10 @@
   } else {
     frame_decision->q_index = 100;
   }
-  return 0;
+  return vpx_rc_ok;
 }
 
-int rc_update_encodeframe_result(
+vpx_rc_status_t rc_update_encodeframe_result(
     vpx_rc_model_t rate_ctrl_model,
     const vpx_rc_encodeframe_result_t *encode_frame_result) {
   const ToyRateCtrl *toy_rate_ctrl =
@@ -100,19 +130,19 @@
       static_cast<ToyRateCtrl *>(rate_ctrl_model);
   EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);
 
-  int64_t ref_pixel_count = 352 * 288 * 3 / 2;
+  const int64_t ref_pixel_count = 352 * 288 * 3 / 2;
   EXPECT_EQ(encode_frame_result->pixel_count, ref_pixel_count);
   if (toy_rate_ctrl->coding_index == kLosslessCodingIndex) {
     EXPECT_EQ(encode_frame_result->sse, 0);
   }
-  return 0;
+  return vpx_rc_ok;
 }
 
-int rc_delete_model(vpx_rc_model_t rate_ctrl_model) {
+vpx_rc_status_t rc_delete_model(vpx_rc_model_t rate_ctrl_model) {
   ToyRateCtrl *toy_rate_ctrl = static_cast<ToyRateCtrl *>(rate_ctrl_model);
   EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);
   delete toy_rate_ctrl;
-  return 0;
+  return vpx_rc_ok;
 }
 
 class ExtRateCtrlTest : public ::libvpx_test::EncoderTest,
@@ -146,11 +176,12 @@
   cfg_.rc_target_bitrate = 24000;
 
   std::unique_ptr<libvpx_test::VideoSource> video;
-  video.reset(new libvpx_test::YUVVideoSource("bus_352x288_420_f20_b8.yuv",
-                                              VPX_IMG_FMT_I420, 352, 288, 30, 1,
-                                              0, kFrameNum));
+  video.reset(new (std::nothrow) libvpx_test::YUVVideoSource(
+      "bus_352x288_420_f20_b8.yuv", VPX_IMG_FMT_I420, 352, 288, 30, 1, 0,
+      kFrameNum));
 
   ASSERT_NE(video.get(), nullptr);
   ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
 }
+
 }  // namespace
--- 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
@@ -4206,6 +4206,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) {
@@ -4482,9 +4503,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;
     }
 
@@ -4773,27 +4799,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
@@ -5098,9 +5103,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
   }
 }
 
@@ -7392,6 +7395,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,
@@ -7539,6 +7566,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,
@@ -7561,26 +7589,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 {
@@ -39,6 +41,11 @@
   int64_t pixel_count;
 } vpx_rc_encodeframe_result_t;
 
+typedef enum vpx_rc_status {
+  vpx_rc_ok = 0,
+  vpx_rc_error = 1,
+} vpx_rc_status_t;
+
 // This is a mirror of vp9's FIRSTPASS_STATS
 // Only spatial_layer_id is omitted
 typedef struct vpx_rc_frame_stats {
@@ -92,7 +99,7 @@
  * \param[in]  ratectrl_config    Pointer to vpx_rc_config_t
  * \param[out] rate_ctrl_model_pt Pointer to vpx_rc_model_t
  */
-typedef int (*vpx_rc_create_model_cb_fn_t)(
+typedef vpx_rc_status_t (*vpx_rc_create_model_cb_fn_t)(
     void *priv, const vpx_rc_config_t *ratectrl_config,
     vpx_rc_model_t *rate_ctrl_model_pt);
 
@@ -105,7 +112,7 @@
  * \param[in]  rate_ctrl_model    rate control model
  * \param[in]  first_pass_stats   first pass stats
  */
-typedef int (*vpx_rc_send_firstpass_stats_cb_fn_t)(
+typedef vpx_rc_status_t (*vpx_rc_send_firstpass_stats_cb_fn_t)(
     vpx_rc_model_t rate_ctrl_model,
     const vpx_rc_firstpass_stats_t *first_pass_stats);
 
@@ -118,7 +125,7 @@
  * \param[in]  encode_frame_info  information of the coding frame
  * \param[out] frame_decision     encode decision of the coding frame
  */
-typedef int (*vpx_rc_get_encodeframe_decision_cb_fn_t)(
+typedef vpx_rc_status_t (*vpx_rc_get_encodeframe_decision_cb_fn_t)(
     vpx_rc_model_t rate_ctrl_model,
     const vpx_rc_encodeframe_info_t *encode_frame_info,
     vpx_rc_encodeframe_decision_t *frame_decision);
@@ -131,7 +138,7 @@
  * \param[in]  rate_ctrl_model     rate control model
  * \param[out] encode_frame_result encode result of the coding frame
  */
-typedef int (*vpx_rc_update_encodeframe_result_cb_fn_t)(
+typedef vpx_rc_status_t (*vpx_rc_update_encodeframe_result_cb_fn_t)(
     vpx_rc_model_t rate_ctrl_model,
     const vpx_rc_encodeframe_result_t *encode_frame_result);
 
@@ -142,7 +149,8 @@
  *
  * \param[in]  rate_ctrl_model     rate control model
  */
-typedef int (*vpx_rc_delete_model_cb_fn_t)(vpx_rc_model_t rate_ctrl_model);
+typedef vpx_rc_status_t (*vpx_rc_delete_model_cb_fn_t)(
+    vpx_rc_model_t rate_ctrl_model);
 
 typedef struct vpx_rc_funcs {
   vpx_rc_create_model_cb_fn_t create_model;