aom: Merge tag 'v3.8.3' into main branch

From 525f35443198f0ffde71ad6e1a447e33e52c7772 Mon Sep 17 00:00:00 2001
From: Wan-Teh Chang <[EMAIL REDACTED]>
Date: Mon, 29 Apr 2024 13:29:14 -0700
Subject: [PATCH 01/14] Ensure thread stack size is at least 256 KB

Fixes cases like musl where the default is lower:
https://wiki.musl-libc.org/functional-differences-from-glibc.html#Thread-stack-size

Bug: aomedia:2754, aomedia:3567
Change-Id: Ia6e211f9b87bc2efe376e7b9f4adb11741850b18
(cherry picked from commit ad5fd34ad9058384a55196f66e2001cc8c2c523f)
---
 aom_util/aom_thread.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/aom_util/aom_thread.c b/aom_util/aom_thread.c
index fa3b0a25e4..14f19e59cd 100644
--- a/aom_util/aom_thread.c
+++ b/aom_util/aom_thread.c
@@ -152,16 +152,18 @@ static int reset(AVxWorker *const worker) {
       // See: https://crbug.com/aomedia/3379
 #if defined(AOM_ADDRESS_SANITIZER) && defined(__APPLE__) && AOM_ARCH_ARM && \
     !defined(NDEBUG)
+    const size_t kMinStackSize = 1024 * 1024;
+#else
+    const size_t kMinStackSize = 256 * 1024;
+#endif
     size_t stacksize;
     if (!pthread_attr_getstacksize(&attr, &stacksize)) {
-      const size_t kMinStackSize = 1 << 20;  // 1 MiB
       if (stacksize < kMinStackSize &&
           pthread_attr_setstacksize(&attr, kMinStackSize)) {
         pthread_attr_destroy(&attr);
         goto Error2;
       }
     }
-#endif
     pthread_mutex_lock(&worker->impl_->mutex_);
     ok = !pthread_create(&worker->impl_->thread_, &attr, thread_loop, worker);
     if (ok) worker->status_ = OK;

From aaccabe09284727775fb051b66505da04615d693 Mon Sep 17 00:00:00 2001
From: Wan-Teh Chang <wtc@google.com>
Date: Thu, 6 Jun 2024 15:12:59 -0700
Subject: [PATCH 02/14] Define pthread_attr_getstacksize/setstacksize

Bug: aomedia:2754, aomedia:3567
Change-Id: I54d9e3e8c1253c9cd9624b3732f4ec0a69d76529
---
 aom_util/aom_thread.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/aom_util/aom_thread.h b/aom_util/aom_thread.h
index ec2ea43491..0e469c0bfd 100644
--- a/aom_util/aom_thread.h
+++ b/aom_util/aom_thread.h
@@ -71,6 +71,20 @@ static INLINE int pthread_attr_destroy(pthread_attr_t *attr) {
   return 0;
 }
 
+static INLINE int pthread_attr_getstacksize(const pthread_attr_t *attr,
+                                            size_t *stacksize) {
+  (void)attr;
+  (void)stacksize;
+  return EINVAL;
+}
+
+static INLINE int pthread_attr_setstacksize(pthread_attr_t *attr,
+                                            size_t stacksize) {
+  (void)attr;
+  (void)stacksize;
+  return EINVAL;
+}
+
 static INLINE int pthread_create(pthread_t *const thread,
                                  const pthread_attr_t *attr,
                                  unsigned int(__stdcall *start)(void *),

From 759713613a9205ffc200ddf2aca3b50e33f4a0c6 Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
Date: Tue, 14 May 2024 17:54:10 -0700
Subject: [PATCH 03/14] update codec config after svc/scale controls

This ensures the encoder state/allocations stay in sync with scaling and
svc layer changes. In the SVC case, depending on the resolution,
differences in the chosen superblock size among layers may have caused a
crash. This was reproducible in WebRTC in screen content mode.

The fix is based on a change by Yuan Tong (tongyuan200097) [1]. It
refreshes the encoder config after AOME_SET_SCALEMODE,
AOME_SET_NUMBER_SPATIAL_LAYERS and AV1E_SET_SVC_PARAMS if no frames have
been encoded. AV1E_SET_SVC_PARAMS was missed in the original change.

[1]: https://aomedia-review.googlesource.com/c/aom/+/171941/2

Bug: chromium:339877165
Change-Id: Ib3d2a123b159898d7c7e19c81e89ff148920e1f1
(cherry picked from commit e42f4b1980bbbc772aa886d8b43a885461d7b89e)
---
 av1/av1_cx_iface.c | 99 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 70 insertions(+), 29 deletions(-)

diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 1175a32ef6..4d5992460f 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -1598,22 +1598,27 @@ static aom_codec_err_t ctrl_get_baseline_gf_interval(aom_codec_alg_priv_t *ctx,
   return AOM_CODEC_OK;
 }
 
+static aom_codec_err_t update_encoder_cfg(aom_codec_alg_priv_t *ctx) {
+  set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
+  av1_check_fpmt_config(ctx->ppi, &ctx->oxcf);
+  bool is_sb_size_changed = false;
+  av1_change_config_seq(ctx->ppi, &ctx->oxcf, &is_sb_size_changed);
+  for (int i = 0; i < ctx->ppi->num_fp_contexts; i++) {
+    av1_change_config(ctx->ppi->parallel_cpi[i], &ctx->oxcf,
+                      is_sb_size_changed);
+  }
+  if (ctx->ppi->cpi_lap != NULL) {
+    av1_change_config(ctx->ppi->cpi_lap, &ctx->oxcf, is_sb_size_changed);
+  }
+  return AOM_CODEC_OK;
+}
+
 static aom_codec_err_t update_extra_cfg(aom_codec_alg_priv_t *ctx,
                                         const struct av1_extracfg *extra_cfg) {
   const aom_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
   if (res == AOM_CODEC_OK) {
     ctx->extra_cfg = *extra_cfg;
-    set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
-    av1_check_fpmt_config(ctx->ppi, &ctx->oxcf);
-    bool is_sb_size_changed = false;
-    av1_change_config_seq(ctx->ppi, &ctx->oxcf, &is_sb_size_changed);
-    for (int i = 0; i < ctx->ppi->num_fp_contexts; i++) {
-      av1_change_config(ctx->ppi->parallel_cpi[i], &ctx->oxcf,
-                        is_sb_size_changed);
-    }
-    if (ctx->ppi->cpi_lap != NULL) {
-      av1_change_config(ctx->ppi->cpi_lap, &ctx->oxcf, is_sb_size_changed);
-    }
+    return update_encoder_cfg(ctx);
   }
   return res;
 }
@@ -3533,11 +3538,23 @@ static aom_codec_err_t ctrl_set_scale_mode(aom_codec_alg_priv_t *ctx,
   aom_scaling_mode_t *const mode = va_arg(args, aom_scaling_mode_t *);
 
   if (mode) {
-    const int res = av1_set_internal_size(
-        &ctx->ppi->cpi->oxcf, &ctx->ppi->cpi->resize_pending_params,
-        mode->h_scaling_mode, mode->v_scaling_mode);
-    av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
-    return (res == 0) ? AOM_CODEC_OK : AOM_CODEC_INVALID_PARAM;
+    AV1EncoderConfig *const oxcf =
+        ctx->ppi->seq_params_locked ? &ctx->ppi->cpi->oxcf : &ctx->oxcf;
+    const int res =
+        av1_set_internal_size(oxcf, &ctx->ppi->cpi->resize_pending_params,
+                              mode->h_scaling_mode, mode->v_scaling_mode);
+    if (res == 0) {
+      // update_encoder_cfg() is somewhat costly and this control may be called
+      // multiple times, so update_encoder_cfg() is only called to ensure frame
+      // and superblock sizes are updated before they're fixed by the first
+      // encode call.
+      if (ctx->ppi->seq_params_locked) {
+        av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
+        return AOM_CODEC_OK;
+      }
+      return update_encoder_cfg(ctx);
+    }
+    return AOM_CODEC_INVALID_PARAM;
   } else {
     return AOM_CODEC_INVALID_PARAM;
   }
@@ -3558,6 +3575,13 @@ static aom_codec_err_t ctrl_set_number_spatial_layers(aom_codec_alg_priv_t *ctx,
   if (number_spatial_layers > MAX_NUM_SPATIAL_LAYERS)
     return AOM_CODEC_INVALID_PARAM;
   ctx->ppi->number_spatial_layers = number_spatial_layers;
+  // update_encoder_cfg() is somewhat costly and this control may be called
+  // multiple times, so update_encoder_cfg() is only called to ensure frame and
+  // superblock sizes are updated before they're fixed by the first encode
+  // call.
+  if (!ctx->ppi->seq_params_locked) {
+    return update_encoder_cfg(ctx);
+  }
   return AOM_CODEC_OK;
 }
 
@@ -3575,8 +3599,6 @@ static aom_codec_err_t ctrl_set_svc_params(aom_codec_alg_priv_t *ctx,
                                            va_list args) {
   AV1_PRIMARY *const ppi = ctx->ppi;
   AV1_COMP *const cpi = ppi->cpi;
-  AV1_COMMON *const cm = &cpi->common;
-  AV1EncoderConfig *oxcf = &cpi->oxcf;
   aom_svc_params_t *const params = va_arg(args, aom_svc_params_t *);
   int64_t target_bandwidth = 0;
   ppi->number_spatial_layers = params->number_spatial_layers;
@@ -3616,19 +3638,38 @@ static aom_codec_err_t ctrl_set_svc_params(aom_codec_alg_priv_t *ctx,
           target_bandwidth += lc->layer_target_bitrate;
       }
     }
-    if (cm->current_frame.frame_number == 0) {
-      if (!cpi->ppi->seq_params_locked) {
-        SequenceHeader *const seq_params = &ppi->seq_params;
-        seq_params->operating_points_cnt_minus_1 =
-            ppi->number_spatial_layers * ppi->number_temporal_layers - 1;
-        av1_init_seq_coding_tools(ppi, &cpi->oxcf, 1);
-      }
+
+    if (ppi->seq_params_locked) {
+      AV1EncoderConfig *const oxcf = &cpi->oxcf;
+      // Keep ctx->oxcf in sync in case further codec controls are made prior
+      // to encoding.
+      ctx->oxcf.rc_cfg.target_bandwidth = oxcf->rc_cfg.target_bandwidth =
+          target_bandwidth;
+      set_primary_rc_buffer_sizes(oxcf, ppi);
+      av1_update_layer_context_change_config(cpi, target_bandwidth);
+      check_reset_rc_flag(cpi);
+    } else {
+      // Note av1_init_layer_context() relies on cpi->oxcf. The order of that
+      // call and the ones in the other half of this block (which
+      // update_encoder_cfg() transitively makes) is important. So we keep
+      // ctx->oxcf and cpi->oxcf in sync here as update_encoder_cfg() will
+      // overwrite cpi->oxcf with ctx->oxcf.
+      ctx->oxcf.rc_cfg.target_bandwidth = cpi->oxcf.rc_cfg.target_bandwidth =
+          target_bandwidth;
+      SequenceHeader *const seq_params = &ppi->seq_params;
+      seq_params->operating_points_cnt_minus_1 =
+          ppi->number_spatial_layers * ppi->number_temporal_layers - 1;
+
       av1_init_layer_context(cpi);
+      // update_encoder_cfg() is somewhat costly and this control may be called
+      // multiple times, so update_encoder_cfg() is only called to ensure frame
+      // and superblock sizes are updated before they're fixed by the first
+      // encode call.
+      return update_encoder_cfg(ctx);
     }
-    oxcf->rc_cfg.target_bandwidth = target_bandwidth;
-    set_primary_rc_buffer_sizes(oxcf, cpi->ppi);
-    av1_update_layer_context_change_config(cpi, target_bandwidth);
-    check_reset_rc_flag(cpi);
+  } else if (!ppi->seq_params_locked) {
+    // Ensure frame and superblock sizes are updated.
+    return update_encoder_cfg(ctx);
   }
   av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
   return AOM_CODEC_OK;

From 3a15245e13e347e2016d1077f9d3cd9a62e76c4e Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
Date: Thu, 16 May 2024 13:44:52 -0700
Subject: [PATCH 04/14] encode_api_test: add repro for chromium 339877165

BUG=chromium:339877165

Change-Id: I69dcc2cda098ec96a34e1e5f7ef557ee8caf5521
(cherry picked from commit 01467cdbd524900eed283660836179fd1b2cd536)
---
 test/encode_api_test.cc | 141 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc
index 9a447b55a9..b48c5a2482 100644
--- a/test/encode_api_test.cc
+++ b/test/encode_api_test.cc
@@ -556,6 +556,147 @@ TEST(EncodeAPI, Buganizer310457427) {
   encoder.Encode(false);
 }
 
+// Reproduces https://crbug.com/339877165.
+TEST(EncodeAPI, Buganizer339877165) {
+  // Initialize libaom encoder.
+  aom_codec_iface_t *const iface = aom_codec_av1_cx();
+  aom_codec_ctx_t enc;
+  aom_codec_enc_cfg_t cfg;
+
+  ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_REALTIME),
+            AOM_CODEC_OK);
+
+  cfg.g_w = 2560;
+  cfg.g_h = 1600;
+  cfg.rc_target_bitrate = 231;
+  cfg.rc_end_usage = AOM_CBR;
+  cfg.g_threads = 8;
+
+  ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
+
+  // From libaom_av1_encoder.cc in WebRTC.
+  ASSERT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 11), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_CDEF, 1), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_TPL_MODEL, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_DELTAQ_MODE, 0), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_ORDER_HINT, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_AQ_MODE, 3), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AOME_SET_MAX_INTRA_BITRATE_PCT, 300),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_COEFF_COST_UPD_FREQ, 3),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MODE_COST_UPD_FREQ, 3),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MV_COST_UPD_FREQ, 3),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_PALETTE, 1), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 1), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_COLUMNS, 2), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_OBMC, 0), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_NOISE_SENSITIVITY, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_WARPED_MOTION, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_GLOBAL_MOTION, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_REF_FRAME_MVS, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SUPERBLOCK_SIZE,
+                              AOM_SUPERBLOCK_SIZE_DYNAMIC),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_CFL_INTRA, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_SMOOTH_INTRA, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_ANGLE_DELTA, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_FILTER_INTRA, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_INTRA_DEFAULT_TX_ONLY, 1),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_DISABLE_TRELLIS_QUANT, 1),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DIST_WTD_COMP, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DIFF_WTD_COMP, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DUAL_FILTER, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTERINTRA_COMP, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTERINTRA_WEDGE, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTRA_EDGE_FILTER, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTRABC, 0), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_MASKED_COMP, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_PAETH_INTRA, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_QM, 0), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_RECT_PARTITIONS, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_RESTORATION, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_SMOOTH_INTERINTRA, 0),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_TX64, 0), AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MAX_REFERENCE_FRAMES, 3),
+            AOM_CODEC_OK);
+  ASSERT_EQ(aom_codec_enc_config_set(&enc, &cfg), AOM_CODEC_OK);
+
+  aom_svc_params_t svc_params = {};
+  svc_params.number_spatial_layers = 2;
+  svc_params.number_temporal_layers = 1;
+  svc_params.max_quantizers[0] = svc_params.max_quantizers[1] = 56;
+  svc_params.min_quantizers[0] = svc_params.min_quantizers[1] = 10;
+  svc_params.scaling_factor_num[0] = svc_params.scaling_factor_num[1] = 1;
+  svc_params.scaling_factor_den[0] = 2;
+  svc_params.scaling_factor_den[1] = 1;
+  svc_params.layer_target_bitrate[0] = cfg.rc_target_bitrate;
+  svc_params.framerate_factor[0] = 1;
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_PARAMS, &svc_params),
+            AOM_CODEC_OK);
+
+  aom_svc_layer_id_t layer_id = {};
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_LAYER_ID, &layer_id),
+            AOM_CODEC_OK);
+
+  aom_svc_ref_frame_config_t ref_frame_config = {};
+  ref_frame_config.refresh[0] = 1;
+  ASSERT_EQ(
+      aom_codec_control(&enc, AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config),
+      AOM_CODEC_OK);
+
+  // Create input image.
+  aom_image_t *const image =
+      CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
+  ASSERT_NE(image, nullptr);
+
+  // Encode layer 0.
+  ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
+
+  layer_id.spatial_layer_id = 1;
+  ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_LAYER_ID, &layer_id),
+            AOM_CODEC_OK);
+
+  ref_frame_config.refresh[0] = 0;
+  ASSERT_EQ(
+      aom_codec_control(&enc, AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config),
+      AOM_CODEC_OK);
+
+  // Encode layer 1.
+  ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
+
+  // Free resources.
+  aom_img_free(image);
+  aom_codec_destroy(&enc);
+}
+
 class EncodeAPIParameterized
     : public testing::TestWithParam<std::tuple<
           /*usage=*/unsigned int, /*speed=*/int, /*aq_mode=*/unsigned int>> {};

From 91001f5f377230337e40df045dbeb7babd703629 Mon Sep 17 00:00:00 2001
From: Yuan Tong <tongyuan200097@gmail.com>
Date: Wed, 8 Mar 2023 16:29:52 +0800
Subject: [PATCH 05/14] Update progressive test to catch more crash case

Update AVIFProgressiveTest.DimensionChangeLargeImageMultiThread to also catch the crash fixed by Ib3d2a123b159898d7c7e19c81e89ff148920e1f1.

BUG: aomedia:3382
Change-Id: I5a65578c7793fdac96c2d41cd71d63a75f7b0d1d
(cherry picked from commit 00392c6223ac9aefc29e0d67929a943836ad8daf)
---
 test/avif_progressive_test.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/avif_progressive_test.cc b/test/avif_progressive_test.cc
index 2a28ca368b..59aebd486f 100644
--- a/test/avif_progressive_test.cc
+++ b/test/avif_progressive_test.cc
@@ -225,8 +225,6 @@ TEST(AVIFProgressiveTest, DimensionChangeLargeImageMultiThread) {
   aom_codec_ctx_t enc;
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 31));
-  EXPECT_EQ(AOM_CODEC_OK,
-            aom_codec_control(&enc, AOME_SET_NUMBER_SPATIAL_LAYERS, 2));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CPUUSED, 6));
   EXPECT_EQ(AOM_CODEC_OK,
             aom_codec_control(&enc, AV1E_SET_ROW_MT, 1));  // MultiThread
@@ -234,6 +232,8 @@ TEST(AVIFProgressiveTest, DimensionChangeLargeImageMultiThread) {
             aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE));
   EXPECT_EQ(AOM_CODEC_OK,
             aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM));
+  EXPECT_EQ(AOM_CODEC_OK,
+            aom_codec_control(&enc, AOME_SET_NUMBER_SPATIAL_LAYERS, 2));
 
   // First frame (layer 0)
   EXPECT_EQ(AOM_CODEC_OK,

From 9dd7563b4b1db7da44baaf4a94b8c8d1c7135aad Mon Sep 17 00:00:00 2001
From: Wan-Teh Chang <wtc@google.com>
Date: Thu, 16 May 2024 14:19:09 -0700
Subject: [PATCH 06/14] Add the DimensionChangeBigImageMultiThread2 test

It is a variant of the DimensionChangeBigImageMultiThread test. The only
difference is that it doesn't have the spatial layers.

This test passes after James Zern's commit e42f4b1980:
https://aomedia-review.googlesource.com/c/aom/+/190181

Bug: aomedia:3382
Change-Id: Ic21e3a71645ac96ebda0b1f2bdcbf709b8f079d5
(cherry picked from commit 6e3e2227eae988a7639d251d042c4fabb7db54d1)
---
 test/avif_progressive_test.cc | 91 ++++++++++++++++++++++++++++++++---
 1 file changed, 85 insertions(+), 6 deletions(-)

diff --git a/test/avif_progressive_test.cc b/test/avif_progressive_test.cc
index 59aebd486f..f3e2ef2af9 100644
--- a/test/avif_progressive_test.cc
+++ b/test/avif_progressive_test.cc
@@ -25,7 +25,7 @@ namespace {
 TEST(AVIFProgressiveTest, QualityChange) {
   constexpr int kWidth = 256;
   constexpr int kHeight = 256;
-  // Dummy buffer of neutral gray samples.
+  // A buffer of neutral gray samples.
   constexpr size_t kBufferSize = 3 * kWidth * kHeight;
   std::vector<unsigned char> buffer(kBufferSize,
                                     static_cast<unsigned char>(128));
@@ -110,7 +110,7 @@ TEST(AVIFProgressiveTest, QualityChange) {
 TEST(AVIFProgressiveTest, DimensionChange) {
   constexpr int kWidth = 256;
   constexpr int kHeight = 256;
-  // Dummy buffer of neutral gray samples.
+  // A buffer of neutral gray samples.
   constexpr size_t kBufferSize = 3 * kWidth * kHeight;
   std::vector<unsigned char> buffer(kBufferSize,
                                     static_cast<unsigned char>(128));
@@ -151,7 +151,7 @@ TEST(AVIFProgressiveTest, DimensionChange) {
   // First frame (layer 0)
   EXPECT_EQ(AOM_CODEC_OK,
             aom_codec_control(&enc, AOME_SET_SPATIAL_LAYER_ID, 0));
-  aom_scaling_mode_t scaling_mode = { AOME_ONETWO, AOME_ONETWO };
+  const aom_scaling_mode_t scaling_mode = { AOME_ONETWO, AOME_ONETWO };
   EXPECT_EQ(AOM_CODEC_OK,
             aom_codec_control(&enc, AOME_SET_SCALEMODE, &scaling_mode));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
@@ -192,10 +192,10 @@ TEST(AVIFProgressiveTest, DimensionChange) {
 // This test reproduces bug aomedia:3382. Certain parameters such as width,
 // height, g_threads, usage, etc. were carefully chosen based on the
 // complicated logic of av1_select_sb_size() to cause an inconsistent sb_size.
-TEST(AVIFProgressiveTest, DimensionChangeLargeImageMultiThread) {
+TEST(AVIFProgressiveTest, DimensionChangeBigImageMultiThread) {
   constexpr int kWidth = 1920;
   constexpr int kHeight = 1080;
-  // Dummy buffer of neutral gray samples.
+  // A buffer of neutral gray samples.
   constexpr size_t kBufferSize = 2 * kWidth * kHeight;
   std::vector<unsigned char> buffer(kBufferSize,
                                     static_cast<unsigned char>(128));
@@ -238,7 +238,7 @@ TEST(AVIFProgressiveTest, DimensionChangeLargeImageMultiThread) {
   // First frame (layer 0)
   EXPECT_EQ(AOM_CODEC_OK,
             aom_codec_control(&enc, AOME_SET_SPATIAL_LAYER_ID, 0));
-  aom_scaling_mode_t scaling_mode = { AOME_ONETWO, AOME_ONETWO };
+  const aom_scaling_mode_t scaling_mode = { AOME_ONETWO, AOME_ONETWO };
   EXPECT_EQ(AOM_CODEC_OK,
             aom_codec_control(&enc, AOME_SET_SCALEMODE, &scaling_mode));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
@@ -276,4 +276,83 @@ TEST(AVIFProgressiveTest, DimensionChangeLargeImageMultiThread) {
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
 }
 
+// A variant of the previous test, without the spatial layers.
+TEST(AVIFProgressiveTest, DimensionChangeBigImageMultiThread2) {
+  constexpr int kWidth = 1920;
+  constexpr int kHeight = 1080;
+  // A buffer of neutral gray samples.
+  constexpr size_t kBufferSize = 2 * kWidth * kHeight;
+  std::vector<unsigned char> buffer(kBufferSize,
+                                    static_cast<unsigned char>(128));
+
+  aom_image_t img;
+  EXPECT_EQ(&img, aom_img_wrap(&img, AOM_IMG_FMT_I420, kWidth, kHeight, 1,
+                               buffer.data()));
+  img.cp = AOM_CICP_CP_UNSPECIFIED;
+  img.tc = AOM_CICP_TC_UNSPECIFIED;
+  img.mc = AOM_CICP_MC_UNSPECIFIED;
+  img.range = AOM_CR_FULL_RANGE;
+
+  aom_codec_iface_t *iface = aom_codec_av1_cx();
+  aom_codec_enc_cfg_t cfg;
+  EXPECT_EQ(AOM_CODEC_OK,
+            aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY));
+  cfg.g_profile = 0;
+  cfg.g_w = img.w;
+  cfg.g_h = img.h;
+  cfg.g_bit_depth = AOM_BITS_8;
+  cfg.g_input_bit_depth = 8;
+  cfg.g_lag_in_frames = 0;
+  cfg.g_threads = 2;  // MultiThread
+  cfg.rc_end_usage = AOM_Q;
+  cfg.rc_min_quantizer = 0;
+  cfg.rc_max_quantizer = 63;
+  aom_codec_ctx_t enc;
+  EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));
+  EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 31));
+  EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CPUUSED, 6));
+  EXPECT_EQ(AOM_CODEC_OK,
+            aom_codec_control(&enc, AV1E_SET_ROW_MT, 1));  // MultiThread
+  EXPECT_EQ(AOM_CODEC_OK,
+            aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE));
+  EXPECT_EQ(AOM_CODEC_OK,
+            aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM));
+
+  // First frame
+  const aom_scaling_mode_t scaling_mode = { AOME_ONETWO, AOME_ONETWO };
+  EXPECT_EQ(AOM_CODEC_OK,
+            aom_codec_control(&enc, AOME_SET_SCALEMODE, &scaling_mode));
+  EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
+  aom_codec_iter_t iter = nullptr;
+  const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
+  ASSERT_NE(pkt, nullptr);
+  EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
+  // pkt->data.frame.flags is 0x1f0011.
+  EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
+  pkt = aom_codec_get_cx_data(&enc, &iter);
+  EXPECT_EQ(pkt, nullptr);
+
+  // Second frame
+  aom_enc_frame_flags_t encode_flags =
+      AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF | AOM_EFLAG_NO_REF_BWD |
+      AOM_EFLAG_NO_REF_ARF2 | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF;
+  EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, encode_flags));
+  iter = nullptr;
+  pkt = aom_codec_get_cx_data(&enc, &iter);
+  ASSERT_NE(pkt, nullptr);
+  EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
+  // pkt->data.frame.flags is 0.
+  EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, 0u);
+  pkt = aom_codec_get_cx_data(&enc, &iter);
+  EXPECT_EQ(pkt, nullptr);
+
+  // Flush encoder
+  EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
+  iter = nullptr;
+  pkt = aom_codec_get_cx_data(&enc, &iter);
+  EXPECT_EQ(pkt, nullptr);
+
+  EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
+}
+
 }  // namespace

From 43500614aad8a2e3d740ca5b3f1451f82046e238 Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
Date: Wed, 29 May 2024 13:26:24 -0700
Subject: [PATCH 07/14] av1_block_error_lp_neon: fix block_size param type

int -> intptr_t. This fixes a Control Flow Integrity (CFI) sanitizer
failure.

This also fixes a -Wmissing-prototypes warning.

This is a port of a broader change that contained the fix:
b44333201b *_neon.c: add missing rtcd includes & CONFIG check

Bug: aomedia:3416
Change-Id: I2e6980fba33631f5bb612d40dfc83b6f2527fe4b
(cherry picked from commit bfd5fa58ddf93f7a716472cddd4fdd9930bd2525)
---
 av1/encoder/arm/neon/av1_error_neon.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/av1/encoder/arm/neon/av1_error_neon.c b/av1/encoder/arm/neon/av1_error_neon.c
index 7d24c7d7af..84c896736e 100644
--- a/av1/encoder/arm/neon/av1_error_neon.c
+++ b/av1/encoder/arm/neon/av1_error_neon.c
@@ -12,6 +12,7 @@
 #include <assert.h>
 
 #include "config/aom_config.h"
+#include "config/av1_rtcd.h"
 
 #include "aom_dsp/aom_dsp_common.h"
 #include "aom_dsp/arm/mem_neon.h"
@@ -60,7 +61,7 @@ int64_t av1_block_error_neon(const tran_low_t *coeff, const tran_low_t *dqcoeff,
 }
 
 int64_t av1_block_error_lp_neon(const int16_t *coeff, const int16_t *dqcoeff,
-                                int block_size) {
+                                intptr_t block_size) {
   int64x2_t error = vdupq_n_s64(0);
 
   assert(block_size >= 8);

From bc47c3707b520b25db4f13e14dae1f4692beeb77 Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
Date: Tue, 30 Apr 2024 12:52:42 -0700
Subject: [PATCH 08/14] noise_model_test.cc: fix -Wc++20-extensions warning

Add an empty fourth argument to INSTANTIATE_TYPED_TEST_SUITE_P().

Fixes:
  aom/test/noise_model_test.cc:536:49: warning: passing no argument for
  the '...' parameter of a variadic macro is a C++20 extension

Change-Id: Id1457ad67a101502f6b811eacfaf483dacd27848
(cherry picked from commit b736e96c15b3efe643a82d394b20c6d44fd225b6)
---
 test/noise_model_test.cc | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/test/noise_model_test.cc b/test/noise_model_test.cc
index b3edcc218e..87f607c155 100644
--- a/test/noise_model_test.cc
+++ b/test/noise_model_test.cc
@@ -532,8 +532,10 @@ typedef ::testing::Types<BitDepthParams<uint8_t, 8, false>,   // lowbd
                          BitDepthParams<uint16_t, 10, true>,  // highbd data
                          BitDepthParams<uint16_t, 12, true> >
     AllBitDepthParams;
+// Note the empty final argument can be removed if C++20 is made the minimum
+// requirement.
 INSTANTIATE_TYPED_TEST_SUITE_P(FlatBlockInstatiation, FlatBlockEstimatorTest,
-                               AllBitDepthParams);
+                               AllBitDepthParams, );
 
 template <typename T>
 class NoiseModelUpdateTest : public ::testing::Test, public T {
@@ -968,8 +970,10 @@ REGISTER_TYPED_TEST_SUITE_P(NoiseModelUpdateTest, UpdateFailsNoFlatBlocks,
                             NoiseStrengthChangeSignalsDifferentNoiseType,
                             NoiseCoeffsSignalsDifferentNoiseType);
 
+// Note the empty final argument can be removed if C++20 is made the minimum
+// requirement.
 INSTANTIATE_TYPED_TEST_SUITE_P(NoiseModelUpdateTestInstatiation,
-                               NoiseModelUpdateTest, AllBitDepthParams);
+                               NoiseModelUpdateTest, AllBitDepthParams, );
 
 TEST(NoiseModelGetGrainParameters, TestLagSize) {
   aom_film_grain_t film_grain;
@@ -1368,5 +1372,7 @@ TYPED_TEST_P(WienerDenoiseTest, GradientTest) {
 REGISTER_TYPED_TEST_SUITE_P(WienerDenoiseTest, InvalidBlockSize,
                             InvalidChromaSubsampling, GradientTest);
 
+// Note the empty final argument can be removed if C++20 is made the minimum
+// requirement.
 INSTANTIATE_TYPED_TEST_SUITE_P(WienerDenoiseTestInstatiation, WienerDenoiseTest,
-                               AllBitDepthParams);
+                               AllBitDepthParams, );

From d31978b8850078a31ec4fc21406020cd76bb6c40 Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
Date: Tue, 30 Apr 2024 16:20:47 -0700
Subject: [PATCH 09/14] common/tools_common.h: port f{seek,tell}o fix from
 libvpx

https://chromium-review.googlesource.com/c/webm/libvpx/+/5074786
bf0755418 Add the needed Android API level predicates.

Bug: aomedia:3561
Change-Id: Ie5c4b3134f3842cd55e5b07e22dffa4ba2584ea8
(cherry picked from commit f4eaf8b55e58102c3f9d2bab7658b9f6063ad400)
---
 common/tools_common.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/common/tools_common.h b/common/tools_common.h
index b31371c670..9d891d1561 100644
--- a/common/tools_common.h
+++ b/common/tools_common.h
@@ -37,8 +37,13 @@ typedef int64_t FileOffset;
 #define fseeko fseeko64
 #define ftello ftello64
 typedef off64_t FileOffset;
-#elif CONFIG_OS_SUPPORT
-#include <sys/types.h> /* NOLINT*/
+#elif CONFIG_OS_SUPPORT &&                                                  \
+    !(defined(__ANDROID__) && __ANDROID_API__ < 24 && !defined(__LP64__) && \
+      defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64)
+/* POSIX.1 has fseeko and ftello. fseeko and ftello are not available before
+ * Android API level 24. See
+ * https://android.googlesource.com/platform/bionic/+/main/docs/32-bit-abi.md */
+#include <sys/types.h> /* NOLINT */
 typedef off_t FileOffset;
 /* Use 32-bit file operations in WebM file format when building ARM
  * executables (.axf) with RVCT. */

From 8e58f5b7f421961b83dceb07c4051c6d6dd424c1 Mon Sep 17 00:00:00 2001
From: Vignesh Venkat <vigneshv@google.com>
Date: Tue, 4 

(Patch may be truncated, please check the link at the top of this post.)