Add av1_estimate_gop_bitrate to tpl_model.
Change-Id: Ic0f2ea5809b027c80fad5510c9739cd5926947a0
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index f46e4f1..f019946 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -1747,6 +1747,7 @@
double av1_laplace_entropy(double q_step, double b, double zero_bin_ratio) {
// zero bin's size is zero_bin_ratio * q_step
// non-zero bin's size is q_step
+ b = AOMMAX(b, TPL_EPSILON);
double z = fmax(exp(-zero_bin_ratio / 2 * q_step / b), TPL_EPSILON);
double h = av1_exponential_entropy(q_step, b);
double r = -(1 - z) * log2(1 - z) - z * log2(z) + z * (h + 1);
@@ -1771,6 +1772,28 @@
return est_rate;
}
+double av1_estimate_gop_bitrate(const unsigned char *q_index_list,
+ const int frame_count,
+ const TplTxfmStats *stats_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];
+
+ /* 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;
+ }
+ return gop_bitrate;
+}
+
double av1_estimate_coeff_entropy(double q_step, double b,
double zero_bin_ratio, int qcoeff) {
int abs_qcoeff = abs(qcoeff);
diff --git a/av1/encoder/tpl_model.h b/av1/encoder/tpl_model.h
index 7c60b1b..0286c16 100644
--- a/av1/encoder/tpl_model.h
+++ b/av1/encoder/tpl_model.h
@@ -306,6 +306,18 @@
const double *abs_coeff_mean,
int coeff_num);
+/*
+ *!\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
+ *
+ */
+double av1_estimate_gop_bitrate(const unsigned char *q_index_list,
+ const int frame_count,
+ const TplTxfmStats *stats);
+
/*!\brief Init data structure storing transform stats
*
*\ingroup tpl_modelling
diff --git a/test/tpl_model_test.cc b/test/tpl_model_test.cc
index 8d5edcd..a29d29c 100644
--- a/test/tpl_model_test.cc
+++ b/test/tpl_model_test.cc
@@ -14,6 +14,7 @@
#include "av1/encoder/cost.h"
#include "av1/encoder/tpl_model.h"
+#include "av1/encoder/encoder.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
namespace {
@@ -140,4 +141,29 @@
EXPECT_EQ(overlap_area, 0);
}
+TEST(TPLModelTest, EstimateFrameRateTest) {
+ /*
+ * Transform size: 16x16
+ * Frame count: 16
+ * Transform block count: 20
+ */
+ const int txfm_size = 256; // 16x16
+ const int frame_count = 16;
+ unsigned char q_index_list[16];
+ TplTxfmStats stats_list[16];
+
+ for (int i = 0; i < frame_count; i++) {
+ q_index_list[i] = 1;
+ stats_list[i].txfm_block_count = 8;
+
+ for (int j = 0; j < txfm_size; j++) {
+ stats_list[i].abs_coeff_sum[j] = 0;
+ }
+ }
+
+ double result =
+ av1_estimate_gop_bitrate(q_index_list, frame_count, stats_list);
+ EXPECT_NEAR(result, 0, 0.1);
+}
+
} // namespace