Commit 15d987ce53 for aom
commit 15d987ce53366326b3773d9a1d87bfe1f68a1dec
Author: Marco Paniconi <marpan@google.com>
Date: Wed Jun 3 05:05:28 2026 +0000
Fix to update num_proj_ref for nonrd mode
Issue occurs when warped_motion is used for real-time mode.
The mi->num_proj_ref was not updated on the final selected
mode in the nonrd_pick_inter_mode(), and not updated
when blocks were merged in the direct_partition_merging().
This causes the decode failure in the issue below.
Note warped-motion is disabled for CONFIG_REALTIME_ONLY.
And the direct_partition_merging speed feature is only
used for real-time speed >= 8.
Unittest added.
Bug: 514696186
Change-Id: I4279b8a0fbe430608044a2068eea1aac767bbd48
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index dd94a24458..82159e83e6 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -4514,6 +4514,13 @@ static inline bool is_switchable_motion_mode_allowed(bool allow_warped_motion,
return (allow_warped_motion || enable_obmc);
}
+static inline int warped_motion_update_num_proj_ref(
+ const struct AV1_COMP *const cpi, const MB_MODE_INFO *const mi) {
+ return cpi->oxcf.motion_mode_cfg.allow_warped_motion && is_inter_block(mi) &&
+ !mi->skip_mode && is_motion_variation_allowed_bsize(mi->bsize) &&
+ !has_second_ref(mi);
+}
+
#if CONFIG_AV1_TEMPORAL_DENOISING
static inline int denoise_svc(const struct AV1_COMP *const cpi) {
return (!cpi->ppi->use_svc ||
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 57cae24ba5..aa0d2e2a6e 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -3748,6 +3748,12 @@ void av1_nonrd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
*rd_cost = search_state.best_rdc;
+ mi->num_proj_ref = 0;
+ if (warped_motion_update_num_proj_ref(cpi, mi)) {
+ int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
+ mi->num_proj_ref = av1_findSamples(cm, xd, pts, pts_inref);
+ }
+
// Reset the xd->block_ref_scale_factors[i], as they may have
// been set to pointer &sf_no_scale, which becomes invalid afer
// this function.
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c
index 2feb14fd3f..09838846b8 100644
--- a/av1/encoder/partition_search.c
+++ b/av1/encoder/partition_search.c
@@ -2924,6 +2924,12 @@ static void direct_partition_merging(AV1_COMP *cpi, ThreadData *td,
this_mi[x_idx + y * mi_params->mi_stride] = this_mi[0];
}
}
+
+ this_mi[0]->num_proj_ref = 0;
+ if (warped_motion_update_num_proj_ref(cpi, this_mi[0])) {
+ int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
+ this_mi[0]->num_proj_ref = av1_findSamples(cm, xd, pts, pts_inref);
+ }
}
}
diff --git a/test/datarate_test.cc b/test/datarate_test.cc
index c777d4a9c0..c33f6365d4 100644
--- a/test/datarate_test.cc
+++ b/test/datarate_test.cc
@@ -759,6 +759,23 @@ TEST_P(DatarateTestPsnr, PerFramePsnr) {
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
+// Test to reproduce decode failure in issue: 514696186.
+TEST_P(DatarateTestRealtime, WarpedMotionEnabled) {
+ if (GET_PARAM(2) != 8) GTEST_SKIP() << "Only run for cpu-used=8";
+
+ ResetModel();
+
+ cfg_.rc_end_usage = AOM_CBR;
+ cfg_.rc_target_bitrate = 100;
+ cfg_.rc_min_quantizer = 2;
+ cfg_.rc_max_quantizer = 52;
+ enable_warped_motion_ = true;
+
+ ::libaom_test::YUVVideoSource video("hantro_odd.yuv", AOM_IMG_FMT_I420, 208,
+ 144, 30, 1, 0, 30);
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+}
+
AV1_INSTANTIATE_TEST_SUITE(DatarateTestLarge,
::testing::Values(::libaom_test::kRealTime),
::testing::Range(5, 7), ::testing::Values(0, 3),
diff --git a/test/datarate_test.h b/test/datarate_test.h
index 9b91cb4148..d531b936e2 100644
--- a/test/datarate_test.h
+++ b/test/datarate_test.h
@@ -70,6 +70,7 @@ class DatarateTest : public ::libaom_test::EncoderTest {
}
avif_mode_ = 0;
lag_realtime_mode_ = 0;
+ enable_warped_motion_ = false;
}
void PreEncodeFrameHook(::libaom_test::VideoSource *video,
@@ -86,7 +87,7 @@ class DatarateTest : public ::libaom_test::EncoderTest {
encoder->Control(AV1E_SET_ROW_MT, 1);
if (cfg_.g_usage == AOM_USAGE_REALTIME) {
encoder->Control(AV1E_SET_ENABLE_GLOBAL_MOTION, 0);
- encoder->Control(AV1E_SET_ENABLE_WARPED_MOTION, 0);
+ encoder->Control(AV1E_SET_ENABLE_WARPED_MOTION, enable_warped_motion_);
encoder->Control(AV1E_SET_ENABLE_RESTORATION, 0);
encoder->Control(AV1E_SET_ENABLE_OBMC, 0);
encoder->Control(AV1E_SET_DELTAQ_MODE, 0);
@@ -290,6 +291,7 @@ class DatarateTest : public ::libaom_test::EncoderTest {
int frame_number_dynamic_[3];
int avif_mode_;
int lag_realtime_mode_;
+ bool enable_warped_motion_;
};
} // namespace