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"