Calculate the bit usage of motion vectors.
av1_tpl_compute_mv_bits iterates through a GOP and accumulates the total
bits used by motion vectors.
av1_tpl_compute_frame_mv_entropy computes the bits used by motion
vectors for a single frame.
The resulting value will be subtracted from the bit budget to improve
the budget estimation.
BUG=aomedia:3045
Change-Id: I8c050747700b479fd0c3c9733aa7e36736d74eba
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index 31bfc77..dde49af 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -2084,3 +2084,60 @@
}
}
#endif // CONFIG_BITRATE_ACCURACY
+
+/* For a GOP, calculate the bits used by motion vectors. */
+double av1_tpl_compute_mv_bits(const TplParams *tpl_data, int gf_group_size,
+ int gf_frame_index) {
+ double total_mv_bits = 0;
+
+ // Loop through each frame.
+ for (int i = gf_frame_index; i < gf_group_size; i++) {
+ TplDepFrame *tpl_frame = &tpl_data->tpl_frame[i];
+ total_mv_bits += av1_tpl_compute_frame_mv_entropy(
+ tpl_frame, tpl_data->tpl_stats_block_mis_log2);
+ }
+
+ return total_mv_bits;
+}
+
+/* Compute the entropy of motion vectors for a single frame. */
+double av1_tpl_compute_frame_mv_entropy(const TplDepFrame *tpl_frame,
+ uint8_t right_shift) {
+ if (!tpl_frame->is_valid) {
+ return 0;
+ }
+
+ int count_row[500] = { 0 };
+ int count_col[500] = { 0 };
+ int n = 0; // number of MVs to process
+
+ const int tpl_stride = tpl_frame->stride;
+ const int step = 1 << right_shift;
+
+ for (int row = 0; row < tpl_frame->mi_rows; row += step) {
+ for (int col = 0; col < tpl_frame->mi_cols; col += step) {
+ const TplDepStats *tpl_stats = &tpl_frame->tpl_stats_ptr[av1_tpl_ptr_pos(
+ row, col, tpl_stride, right_shift)];
+ int_mv mv = tpl_stats->mv[tpl_stats->ref_frame_index[0]];
+ count_row[clamp(mv.as_mv.row, 0, 499)] += 1;
+ count_col[clamp(mv.as_mv.row, 0, 499)] += 1;
+ n += 1;
+ }
+ }
+
+ // Estimate the bits used using the entropy formula.
+ double rate_row = 0;
+ double rate_col = 0;
+ for (int i = 0; i < 500; i++) {
+ if (count_row[i] != 0) {
+ double p = count_row[i] / (double)n;
+ rate_row += count_row[i] * -log2(p);
+ }
+ if (count_col[i] != 0) {
+ double p = count_col[i] / (double)n;
+ rate_col += count_col[i] * -log2(p);
+ }
+ }
+
+ return rate_row + rate_col;
+}
diff --git a/av1/encoder/tpl_model.h b/av1/encoder/tpl_model.h
index bc319b8..ffebc44 100644
--- a/av1/encoder/tpl_model.h
+++ b/av1/encoder/tpl_model.h
@@ -560,6 +560,27 @@
aom_bit_depth_t bit_depth);
#endif // CONFIG_BITRATE_ACCURACY
+/*!\brief For a GOP, calculate the bits used by motion vectors.
+ *
+ * \param[in] tpl_data TPL struct
+ * \param[in] gf_group Pointer to the GOP
+ * \param[in] gf_frame_index Current frame index
+ *
+ * \return Bits used by the motion vectors for the GOP.
+ */
+double av1_tpl_compute_mv_bits(const TplParams *tpl_data, int gf_group_size,
+ int gf_frame_index);
+
+/*!\brief Compute the entropy of motion vectors for a single frame.
+ *
+ * \param[in] tpl_frame TPL frame struct
+ * \param[in] right_shift right shift value for step
+ *
+ * \return Bits used by the motion vectors for one frame.
+ */
+double av1_tpl_compute_frame_mv_entropy(const TplDepFrame *tpl_frame,
+ uint8_t right_shift);
+
/*!\endcond */
#ifdef __cplusplus
} // extern "C"