Commit 8e65bb0620 for aom
commit 8e65bb0620f2aa6586cdcfe54eef12b843b5b334
Author: Lin Zheng <linzhen@google.com>
Date: Wed Sep 9 13:59:11 2026 +0000
Reallocate frame buffer on resolution change in lookahead
Fix the assertion by calling aom_realloc_frame_buffer() whenever
new_dimensions is true, ensuring the frame buffer and its
associated image pyramid are reallocated properly for the new frame size.
Bug: 558434716
Change-Id: I0f7f92798a0a1aec60c2c7f623f3c227d78c784c
diff --git a/av1/encoder/lookahead.c b/av1/encoder/lookahead.c
index ee2e0659d1..7dcabf9710 100644
--- a/av1/encoder/lookahead.c
+++ b/av1/encoder/lookahead.c
@@ -105,7 +105,7 @@ int av1_lookahead_push(struct lookahead_ctx *ctx, const YV12_BUFFER_CONFIG *src,
int uv_height = src->uv_crop_height;
int subsampling_x = src->subsampling_x;
int subsampling_y = src->subsampling_y;
- int larger_dimensions, new_dimensions;
+ int new_dimensions;
assert(ctx->read_ctxs[ENCODE_STAGE].valid == 1);
if (ctx->read_ctxs[ENCODE_STAGE].sz + ctx->max_pre_frames > ctx->max_sz)
@@ -122,31 +122,13 @@ int av1_lookahead_push(struct lookahead_ctx *ctx, const YV12_BUFFER_CONFIG *src,
height != buf->img.y_crop_height ||
uv_width != buf->img.uv_crop_width ||
uv_height != buf->img.uv_crop_height;
- larger_dimensions =
- width > buf->img.y_crop_width || height > buf->img.y_crop_height ||
- uv_width > buf->img.uv_crop_width || uv_height > buf->img.uv_crop_height;
- assert(!larger_dimensions || new_dimensions);
-
- if (larger_dimensions) {
- YV12_BUFFER_CONFIG new_img;
- memset(&new_img, 0, sizeof(new_img));
- if (aom_alloc_frame_buffer(&new_img, width, height, subsampling_x,
- subsampling_y, use_highbitdepth,
- AOM_BORDER_IN_PIXELS, 0, alloc_pyramid, 0))
+
+ if (new_dimensions) {
+ if (aom_realloc_frame_buffer(&buf->img, width, height, subsampling_x,
+ subsampling_y, use_highbitdepth,
+ AOM_BORDER_IN_PIXELS, 0, NULL, NULL, NULL,
+ alloc_pyramid, 0))
return 1;
- aom_free_frame_buffer(&buf->img);
- buf->img = new_img;
- } else if (new_dimensions) {
- buf->img.y_width = src->y_width;
- buf->img.y_height = src->y_height;
- buf->img.uv_width = src->uv_width;
- buf->img.uv_height = src->uv_height;
- buf->img.y_crop_width = src->y_crop_width;
- buf->img.y_crop_height = src->y_crop_height;
- buf->img.uv_crop_width = src->uv_crop_width;
- buf->img.uv_crop_height = src->uv_crop_height;
- buf->img.subsampling_x = src->subsampling_x;
- buf->img.subsampling_y = src->subsampling_y;
}
av1_copy_and_extend_frame(src, &buf->img);
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc
index e67282226d..cf8d636e19 100644
--- a/test/encode_api_test.cc
+++ b/test/encode_api_test.cc
@@ -2684,4 +2684,63 @@ TEST(EncodeAPI, Buganizer503810640V2) {
ASSERT_EQ(aom_codec_destroy(&codec), AOM_CODEC_OK);
}
+#if !CONFIG_REALTIME_ONLY
+TEST(EncodeAPI, Buganizer558434716) {
+ aom_codec_iface_t *iface = aom_codec_av1_cx();
+ aom_codec_enc_cfg_t cfg;
+ ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY),
+ AOM_CODEC_OK);
+
+ cfg.g_w = 128;
+ cfg.g_h = 96;
+ cfg.g_forced_max_frame_width = 1920;
+ cfg.g_forced_max_frame_height = 1080;
+ cfg.g_pass = AOM_RC_ONE_PASS;
+ cfg.g_lag_in_frames = 0;
+ cfg.g_threads = 1;
+
+ aom_codec_ctx_t enc;
+ ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
+
+ aom_image_t *img_small = aom_img_alloc(nullptr, AOM_IMG_FMT_I420, 128, 96, 1);
+ ASSERT_NE(img_small, nullptr);
+ FillImage(img_small, 128);
+
+ aom_image_t *img_large =
+ aom_img_alloc(nullptr, AOM_IMG_FMT_I420, 320, 240, 1);
+ ASSERT_NE(img_large, nullptr);
+ FillImage(img_large, 128);
+
+ // Frame 0 at 128x96
+ ASSERT_EQ(aom_codec_encode(&enc, img_small, 0, 1, 0), AOM_CODEC_OK);
+
+ // Switch to larger resolution
+ cfg.g_w = 320;
+ cfg.g_h = 240;
+ ASSERT_EQ(aom_codec_enc_config_set(&enc, &cfg), AOM_CODEC_OK);
+
+ // Frame 1 at 320x240
+ ASSERT_EQ(aom_codec_encode(&enc, img_large, 1, 1, AOM_EFLAG_FORCE_KF),
+ AOM_CODEC_OK);
+
+ // Switch back to smaller resolution
+ cfg.g_w = 128;
+ cfg.g_h = 96;
+ ASSERT_EQ(aom_codec_enc_config_set(&enc, &cfg), AOM_CODEC_OK);
+
+ // Frame 2 at 128x96 (keyframe)
+ ASSERT_EQ(aom_codec_encode(&enc, img_small, 2, 1, AOM_EFLAG_FORCE_KF),
+ AOM_CODEC_OK);
+
+ // Frames 3+ at 128x96 (interframes referencing frame 2)
+ for (int i = 3; i < 8; ++i) {
+ ASSERT_EQ(aom_codec_encode(&enc, img_small, i, 1, 0), AOM_CODEC_OK);
+ }
+
+ aom_img_free(img_small);
+ aom_img_free(img_large);
+ ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
+}
+#endif // !CONFIG_REALTIME_ONLY
+
} // namespace