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;