aom: Fix divide by zero.

From 0a23e12394843688df13f8ff5121c26424e5eb7a Mon Sep 17 00:00:00 2001
From: Paul Wilkins <[EMAIL REDACTED]>
Date: Tue, 23 Jan 2024 16:58:32 +0000
Subject: [PATCH] Fix divide by zero.

Raised in issue Issue # 3523:

Explicitly check p_rc->rolling_target_bits > 0 for the identified case.

Also:-

When initializing  p_rc->rolling_actual_bits and
p_rc->rolling_target_bits force to max(1,x).

In the encoder interface range check target rate > 0.

Bug: aomedia:3523
Change-Id: If7ba7e98af627227498443c2e9a739c65ec8d68b
(cherry picked from commit 77cf417565ad2c527d5c351927f11db3764fd93c)
---
 av1/av1_cx_iface.c           | 6 ++++++
 av1/encoder/pass2_strategy.c | 3 ++-
 av1/encoder/ratectrl.c       | 8 ++++----
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 1175a32ef6..0ad6f439e4 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -623,6 +623,11 @@ static aom_codec_err_t allocate_and_set_string(const char *src,
       ERROR(#memb " out of range [" #lo ".." #hi "]"); \
   } while (0)
 
+#define RANGE_CHECK_LO(p, memb, lo)                                     \
+  do {                                                                  \
+    if (!((p)->memb >= (lo))) ERROR(#memb " out of range [" #lo "..]"); \
+  } while (0)
+
 #define RANGE_CHECK_HI(p, memb, hi)                                     \
   do {                                                                  \
     if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \
@@ -662,6 +667,7 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
   RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
   RANGE_CHECK_HI(cfg, g_profile, MAX_PROFILES - 1);
 
+  RANGE_CHECK_LO(cfg, rc_target_bitrate, 1);
   RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
   RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
   RANGE_CHECK_BOOL(extra_cfg, lossless);
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index d85440df5e..68b10567b4 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -4228,7 +4228,8 @@ void av1_twopass_postencode_update(AV1_COMP *cpi) {
   twopass->kf_group_bits = AOMMAX(twopass->kf_group_bits, 0);
 
   // If the rate control is drifting consider adjustment to min or maxq.
-  if ((rc_cfg->mode != AOM_Q) && !cpi->rc.is_src_frame_alt_ref) {
+  if ((rc_cfg->mode != AOM_Q) && !cpi->rc.is_src_frame_alt_ref &&
+      (p_rc->rolling_target_bits > 0)) {
     int minq_adj_limit;
     int maxq_adj_limit;
     minq_adj_limit =
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 9062136aad..1f1ff81386 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -404,10 +404,10 @@ void av1_primary_rc_init(const AV1EncoderConfig *oxcf,
   p_rc->rate_correction_factors[KF_STD] = 1.0;
   p_rc->bits_off_target = p_rc->starting_buffer_level;
 
-  p_rc->rolling_target_bits =
-      (int)(oxcf->rc_cfg.target_bandwidth / oxcf->input_cfg.init_framerate);
-  p_rc->rolling_actual_bits =
-      (int)(oxcf->rc_cfg.target_bandwidth / oxcf->input_cfg.init_framerate);
+  p_rc->rolling_target_bits = AOMMAX(
+      1, (int)(oxcf->rc_cfg.target_bandwidth / oxcf->input_cfg.init_framerate));
+  p_rc->rolling_actual_bits = AOMMAX(
+      1, (int)(oxcf->rc_cfg.target_bandwidth / oxcf->input_cfg.init_framerate));
 }
 
 void av1_rc_init(const AV1EncoderConfig *oxcf, RATE_CONTROL *rc) {