Fixed av1_estimate_gop_bitrate
Only compute coefficient rate when it's tpl stats is valid
Change-Id: If278f138ffdd8d69fd9699660d4d3c32bd6c5422
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index a21e0fa..d2c1b7d 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -1869,25 +1869,28 @@
double av1_estimate_gop_bitrate(const int *q_index_list, const int frame_count,
const TplTxfmStats *stats_list,
+ const int *stats_valid_list,
double *bitrate_byframe_list) {
double gop_bitrate = 0;
for (int frame_index = 0; frame_index < frame_count; frame_index++) {
- int q_index = q_index_list[frame_index];
- TplTxfmStats frame_stats = stats_list[frame_index];
+ if (stats_valid_list[frame_index]) {
+ int q_index = q_index_list[frame_index];
+ TplTxfmStats frame_stats = stats_list[frame_index];
- /* Convert to mean absolute deviation */
- double abs_coeff_mean[256] = { 0 };
- for (int i = 0; i < 256; i++) {
- abs_coeff_mean[i] =
- frame_stats.abs_coeff_sum[i] / frame_stats.txfm_block_count;
- }
+ /* Convert to mean absolute deviation */
+ double abs_coeff_mean[256] = { 0 };
+ for (int i = 0; i < 256; i++) {
+ abs_coeff_mean[i] =
+ frame_stats.abs_coeff_sum[i] / frame_stats.txfm_block_count;
+ }
- double frame_bitrate = av1_laplace_estimate_frame_rate(
- q_index, frame_stats.txfm_block_count, abs_coeff_mean, 256);
- gop_bitrate += frame_bitrate;
+ double frame_bitrate = av1_laplace_estimate_frame_rate(
+ q_index, frame_stats.txfm_block_count, abs_coeff_mean, 256);
+ gop_bitrate += frame_bitrate;
- if (bitrate_byframe_list != NULL) {
- bitrate_byframe_list[frame_index] = frame_bitrate;
+ if (bitrate_byframe_list != NULL) {
+ bitrate_byframe_list[frame_index] = frame_bitrate;
+ }
}
}
return gop_bitrate;
@@ -1946,13 +1949,20 @@
}
#endif // CONFIG_RD_COMMAND
+void get_tpl_stats_valid_list(const TplParams *tpl_data, int gop_size,
+ int *stats_valid_list) {
+ for (int i = 0; i < gop_size; ++i) {
+ stats_valid_list[i] = av1_tpl_stats_ready(tpl_data, i);
+ }
+}
+
/*
* Estimate the optimal base q index for a GOP.
*/
int av1_q_mode_estimate_base_q(const GF_GROUP *gf_group,
const TplTxfmStats *txfm_stats_list,
- double bit_budget, int gf_frame_index,
- double arf_qstep_ratio,
+ const int *stats_valid_list, double bit_budget,
+ int gf_frame_index, double arf_qstep_ratio,
aom_bit_depth_t bit_depth, double scale_factor,
int *q_index_list,
double *estimated_bitrate_byframe) {
@@ -1962,19 +1972,19 @@
av1_q_mode_compute_gop_q_indices(gf_frame_index, q_max, arf_qstep_ratio,
bit_depth, gf_group, q_index_list);
- double q_max_estimate = av1_estimate_gop_bitrate(q_index_list, gf_group->size,
- txfm_stats_list, NULL);
+ double q_max_estimate = av1_estimate_gop_bitrate(
+ q_index_list, gf_group->size, txfm_stats_list, stats_valid_list, NULL);
av1_q_mode_compute_gop_q_indices(gf_frame_index, q_min, arf_qstep_ratio,
bit_depth, gf_group, q_index_list);
- double q_min_estimate = av1_estimate_gop_bitrate(q_index_list, gf_group->size,
- txfm_stats_list, NULL);
+ double q_min_estimate = av1_estimate_gop_bitrate(
+ q_index_list, gf_group->size, txfm_stats_list, stats_valid_list, NULL);
while (true) {
av1_q_mode_compute_gop_q_indices(gf_frame_index, q, arf_qstep_ratio,
bit_depth, gf_group, q_index_list);
- double estimate = av1_estimate_gop_bitrate(q_index_list, gf_group->size,
- txfm_stats_list, NULL);
+ double estimate = av1_estimate_gop_bitrate(
+ q_index_list, gf_group->size, txfm_stats_list, stats_valid_list, NULL);
estimate *= scale_factor;
@@ -2004,7 +2014,7 @@
av1_q_mode_compute_gop_q_indices(gf_frame_index, q, arf_qstep_ratio,
bit_depth, gf_group, q_index_list);
av1_estimate_gop_bitrate(q_index_list, gf_group->size, txfm_stats_list,
- estimated_bitrate_byframe);
+ stats_valid_list, estimated_bitrate_byframe);
return q;
}
@@ -2069,9 +2079,11 @@
av1_tpl_get_qstep_ratio(tpl_data, gf_frame_index);
// We update the q indices in vbr_rc_info in vbr_rc_info->q_index_list
// rather than gf_group->q_val to avoid conflicts with the existing code.
+ int stats_valid_list[MAX_LENGTH_TPL_FRAME_STATS] = { 0 };
+ get_tpl_stats_valid_list(tpl_data, gf_group->size, stats_valid_list);
av1_q_mode_estimate_base_q(
- gf_group, tpl_data->txfm_stats_list, gop_bit_budget, gf_frame_index,
- arf_qstep_ratio, bit_depth, vbr_rc_info->scale_factor,
+ gf_group, tpl_data->txfm_stats_list, stats_valid_list, gop_bit_budget,
+ gf_frame_index, arf_qstep_ratio, bit_depth, vbr_rc_info->scale_factor,
vbr_rc_info->q_index_list, vbr_rc_info->estimated_bitrate_byframe);
}
}
diff --git a/av1/encoder/tpl_model.h b/av1/encoder/tpl_model.h
index c24d77e..922a6e5 100644
--- a/av1/encoder/tpl_model.h
+++ b/av1/encoder/tpl_model.h
@@ -405,16 +405,19 @@
/*
*!\brief Compute the number of bits needed to encode a GOP
*
- * \param[in] q_index_list array of q_index, one per frame
- * \param[in] frame_count number of frames in the GOP
- * \param[in] stats array of transform stats, one per frame
- * \param[in] bitrate_byframe_list Array to keep track of frame bitrate
+ * \param[in] q_index_list array of q_index, one per frame
+ * \param[in] frame_count number of frames in the GOP
+ * \param[in] stats array of transform stats, one per frame
+ * \param[in] stats_valid_list List indicates whether transform stats
+ * exists
+ * \param[out] bitrate_byframe_list Array to keep track of frame bitrate
*
* \return The estimated GOP bitrate.
*
*/
double av1_estimate_gop_bitrate(const int *q_index_list, const int frame_count,
const TplTxfmStats *stats,
+ const int *stats_valid_list,
double *bitrate_byframe_list);
/*
@@ -510,21 +513,23 @@
* a binary search to find q to achieve the specified bit rate.
*
* \param[in] gf_group GOP structure
- * \param[in] stats Transform stats struct
+ * \param[in] txfm_stats_list Transform stats struct
+ * \param[in] stats_valid_list List indicates whether transform stats
+ * exists
* \param[in] bit_budget The specified bit budget to achieve
* \param[in] gf_frame_index current frame in the GOP
* \param[in] arf_qstep_ratio ARF q step ratio
* \param[in] bit_depth bit depth
* \param[in] scale_factor Scale factor to improve budget estimation
- * \param[in] q_index_list array of q_index, one per frame
- * \param[in] estimated_bitrate_byframe bit depth
+ * \param[out] q_index_list array of q_index, one per frame
+ * \param[out] estimated_bitrate_byframe bits usage per frame in the GOP
*
* \return Returns the optimal base q index to use.
*/
int av1_q_mode_estimate_base_q(const struct GF_GROUP *gf_group,
const TplTxfmStats *txfm_stats_list,
- double bit_budget, int gf_frame_index,
- double arf_qstep_ratio,
+ const int *stats_valid_list, double bit_budget,
+ int gf_frame_index, double arf_qstep_ratio,
aom_bit_depth_t bit_depth, double scale_factor,
int *q_index_list,
double *estimated_bitrate_byframe);
diff --git a/test/tpl_model_test.cc b/test/tpl_model_test.cc
index d426ef1..3094c6c 100644
--- a/test/tpl_model_test.cc
+++ b/test/tpl_model_test.cc
@@ -156,10 +156,12 @@
const int txfm_size = 256; // 16x16
const int frame_count = 16;
int q_index_list[16];
+ int valid_list[16];
TplTxfmStats stats_list[16];
for (int i = 0; i < frame_count; i++) {
q_index_list[i] = 1;
+ valid_list[i] = 1;
stats_list[i].txfm_block_count = 8;
for (int j = 0; j < txfm_size; j++) {
@@ -167,8 +169,8 @@
}
}
- double result =
- av1_estimate_gop_bitrate(q_index_list, frame_count, stats_list, NULL);
+ double result = av1_estimate_gop_bitrate(q_index_list, frame_count,
+ stats_list, valid_list, NULL);
EXPECT_NEAR(result, 0, 0.1);
}
@@ -234,16 +236,17 @@
* that achieves the specified bit budget.
*/
int find_gop_q_iterative(double bit_budget, double arf_qstep_ratio,
- GF_GROUP gf_group, TplTxfmStats *stats_list,
- int gf_frame_index, aom_bit_depth_t bit_depth) {
+ GF_GROUP gf_group, const int *stats_valid_list,
+ TplTxfmStats *stats_list, int gf_frame_index,
+ aom_bit_depth_t bit_depth) {
// Brute force iterative method to find the optimal q.
// Use the result to test against the binary search result.
// Initial estimate when q = 255
av1_q_mode_compute_gop_q_indices(gf_frame_index, 255, arf_qstep_ratio,
bit_depth, &gf_group, gf_group.q_val);
- double curr_estimate =
- av1_estimate_gop_bitrate(gf_group.q_val, gf_group.size, stats_list, NULL);
+ double curr_estimate = av1_estimate_gop_bitrate(
+ gf_group.q_val, gf_group.size, stats_list, stats_valid_list, NULL);
double best_estimate_budget_distance = fabs(curr_estimate - bit_budget);
int best_q = 255;
@@ -251,8 +254,8 @@
for (int q = 254; q >= 0; q--) {
av1_q_mode_compute_gop_q_indices(gf_frame_index, q, arf_qstep_ratio,
bit_depth, &gf_group, gf_group.q_val);
- curr_estimate = av1_estimate_gop_bitrate(gf_group.q_val, gf_group.size,
- stats_list, NULL);
+ curr_estimate = av1_estimate_gop_bitrate(
+ gf_group.q_val, gf_group.size, stats_list, stats_valid_list, NULL);
double curr_estimate_budget_distance = fabs(curr_estimate - bit_budget);
if (curr_estimate_budget_distance <= best_estimate_budget_distance) {
best_estimate_budget_distance = curr_estimate_budget_distance;
@@ -269,12 +272,14 @@
int q_index_list[25];
const int gf_group_update_types[25] = { 0, 3, 6, 6, 6, 1, 5, 1, 5, 6, 1, 5, 1,
5, 6, 6, 1, 5, 1, 5, 6, 1, 5, 1, 4 };
+ int stats_valid_list[25] = { 0 };
const int gf_frame_index = 0;
const double arf_qstep_ratio = 2;
const aom_bit_depth_t bit_depth = AOM_BITS_8;
const double scale_factor = 1.0;
for (int i = 0; i < gf_group.size; i++) {
+ stats_valid_list[i] = 1;
gf_group.update_type[i] = gf_group_update_types[i];
stats_list[i].txfm_block_count = 8;
@@ -291,11 +296,11 @@
for (double bit_budget : bit_budgets) {
// Binary search method to find the optimal q.
const int result = av1_q_mode_estimate_base_q(
- &gf_group, stats_list, bit_budget, gf_frame_index, arf_qstep_ratio,
- bit_depth, scale_factor, q_index_list, NULL);
- const int test_result =
- find_gop_q_iterative(bit_budget, arf_qstep_ratio, gf_group, stats_list,
- gf_frame_index, bit_depth);
+ &gf_group, stats_list, stats_valid_list, bit_budget, gf_frame_index,
+ arf_qstep_ratio, bit_depth, scale_factor, q_index_list, NULL);
+ const int test_result = find_gop_q_iterative(
+ bit_budget, arf_qstep_ratio, gf_group, stats_valid_list, stats_list,
+ gf_frame_index, bit_depth);
if (bit_budget == 0) {
EXPECT_EQ(result, 255);