Add unit test to check the presence of forward key frame.
ForwardKeyEncodePresenceTest checks the presense of forward
key frame for multiple encode configurations.
Change-Id: I8d24a9190fcb73fbeac8d06ec14f3c92871a97ef
diff --git a/aom/aomdx.h b/aom/aomdx.h
index 1ec0db8..43fa85f 100644
--- a/aom/aomdx.h
+++ b/aom/aomdx.h
@@ -307,6 +307,8 @@
AV1D_SET_SKIP_FILM_GRAIN,
AOM_DECODER_CTRL_ID_MAX,
+
+ AOMD_GET_FWD_KF_PRESENT,
};
/*!\cond */
@@ -333,6 +335,9 @@
AOM_CTRL_USE_TYPE(AOMD_GET_LAST_QUANTIZER, int *)
#define AOM_CTRL_AOMD_GET_LAST_QUANTIZER
+AOM_CTRL_USE_TYPE(AOMD_GET_FWD_KF_PRESENT, int *)
+#define AOM_CTRL_AOMD_GET_FWD_KF_PRESENT
+
AOM_CTRL_USE_TYPE(AV1D_GET_DISPLAY_SIZE, int *)
#define AOM_CTRL_AV1D_GET_DISPLAY_SIZE
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c
index e621cd2..b3a09d5 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -467,7 +467,7 @@
frame_worker_data->pbi->output_all_layers = ctx->output_all_layers;
frame_worker_data->pbi->ext_tile_debug = ctx->ext_tile_debug;
frame_worker_data->pbi->row_mt = ctx->row_mt;
-
+ frame_worker_data->pbi->is_fwd_kf_present = 0;
worker->hook = frame_worker_hook;
init_buffer_callbacks(ctx);
@@ -969,6 +969,14 @@
return AOM_CODEC_OK;
}
+static aom_codec_err_t ctrl_get_fwd_kf_value(aom_codec_alg_priv_t *ctx,
+ va_list args) {
+ int *const arg = va_arg(args, int *);
+ if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
+ *arg = ((FrameWorkerData *)ctx->frame_worker->data1)->pbi->is_fwd_kf_present;
+ return AOM_CODEC_OK;
+}
+
static aom_codec_err_t ctrl_get_frame_corrupted(aom_codec_alg_priv_t *ctx,
va_list args) {
int *corrupted = va_arg(args, int *);
@@ -1361,6 +1369,7 @@
{ AV1_GET_REFERENCE, ctrl_get_reference },
{ AV1D_GET_FRAME_HEADER_INFO, ctrl_get_frame_header_info },
{ AV1D_GET_TILE_DATA, ctrl_get_tile_data },
+ { AOMD_GET_FWD_KF_PRESENT, ctrl_get_fwd_kf_value },
CTRL_MAP_END,
};
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 8563c2d..98a4dc6 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -4545,6 +4545,8 @@
}
cm->show_frame = aom_rb_read_bit(rb);
+ if (cm->show_frame == 0 && cm->current_frame.frame_type == KEY_FRAME)
+ pbi->is_fwd_kf_present = 1;
if (seq_params->still_picture &&
(current_frame->frame_type != KEY_FRAME || !cm->show_frame)) {
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h
index a5e0f29..b756f62 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -326,6 +326,7 @@
int skip_film_grain;
int is_annexb;
int valid_for_referencing[REF_FRAMES];
+ int is_fwd_kf_present;
} AV1Decoder;
// Returns 0 on success. Sets pbi->common.error.error_code to a nonzero error
diff --git a/test/fwd_kf_test.cc b/test/fwd_kf_test.cc
index 50c2f36..d26108d 100644
--- a/test/fwd_kf_test.cc
+++ b/test/fwd_kf_test.cc
@@ -113,4 +113,84 @@
AV1_INSTANTIATE_TEST_CASE(ForwardKeyTest,
::testing::Values(::libaom_test::kTwoPassGood),
::testing::ValuesIn(kTestParams));
+
+typedef struct {
+ const unsigned int min_kf_dist;
+ const unsigned int max_kf_dist;
+} kfIntervalParam;
+
+const kfIntervalParam kfTestParams[] = {
+ { 0, 10 }, { 10, 10 }, { 0, 30 }, { 30, 30 }
+};
+
+std::ostream &operator<<(std::ostream &os, const kfIntervalParam &test_arg) {
+ return os << "kfIntervalParam { min_kf_dist:" << test_arg.min_kf_dist
+ << " max_kf_dist:" << test_arg.max_kf_dist << " }";
+}
+
+// This class is used to test the presence of forward key frame.
+class ForwardKeyPresenceTestLarge
+ : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode,
+ kfIntervalParam, aom_rc_mode>,
+ public ::libaom_test::EncoderTest {
+ protected:
+ ForwardKeyPresenceTestLarge()
+ : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
+ kf_dist_param_(GET_PARAM(2)), end_usage_check_(GET_PARAM(3)) {}
+ virtual ~ForwardKeyPresenceTestLarge() {}
+
+ virtual void SetUp() {
+ InitializeConfig();
+ SetMode(encoding_mode_);
+ const aom_rational timebase = { 1, 30 };
+ cfg_.g_timebase = timebase;
+ cfg_.rc_end_usage = end_usage_check_;
+ cfg_.g_threads = 1;
+ cfg_.kf_min_dist = kf_dist_param_.min_kf_dist;
+ cfg_.kf_max_dist = kf_dist_param_.max_kf_dist;
+ cfg_.fwd_kf_enabled = 1;
+ cfg_.g_lag_in_frames = 19;
+ }
+
+ virtual bool DoDecode() const { return 1; }
+
+ virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
+ ::libaom_test::Encoder *encoder) {
+ if (video->frame() == 0) {
+ encoder->Control(AOME_SET_CPUUSED, 5);
+ encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
+ }
+ }
+
+ virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
+ libaom_test::Decoder *decoder) {
+ EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
+ if (is_fwd_kf_present_ != 1 && AOM_CODEC_OK == res_dec) {
+ aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
+ AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_FWD_KF_PRESENT,
+ &is_fwd_kf_present_);
+ }
+ return AOM_CODEC_OK == res_dec;
+ }
+
+ ::libaom_test::TestMode encoding_mode_;
+ const kfIntervalParam kf_dist_param_;
+ int is_fwd_kf_present_;
+ aom_rc_mode end_usage_check_;
+};
+
+TEST_P(ForwardKeyPresenceTestLarge, ForwardKeyEncodePresenceTest) {
+ is_fwd_kf_present_ = 0;
+ libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
+ cfg_.g_timebase.den, cfg_.g_timebase.num,
+ 0, 150);
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+ ASSERT_EQ(is_fwd_kf_present_, 1);
+}
+
+AV1_INSTANTIATE_TEST_CASE(ForwardKeyPresenceTestLarge,
+ ::testing::Values(::libaom_test::kOnePassGood,
+ ::libaom_test::kTwoPassGood),
+ ::testing::ValuesIn(kfTestParams),
+ ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ));
} // namespace
diff --git a/test/test.cmake b/test/test.cmake
index 5988bda..6c7d281 100644
--- a/test/test.cmake
+++ b/test/test.cmake
@@ -67,7 +67,6 @@
"${AOM_ROOT}/test/encode_test_driver.cc"
"${AOM_ROOT}/test/encode_test_driver.h"
"${AOM_ROOT}/test/end_to_end_test.cc"
- "${AOM_ROOT}/test/fwd_kf_test.cc"
"${AOM_ROOT}/test/gf_pyr_height_test.cc"
"${AOM_ROOT}/test/rt_end_to_end_test.cc"
"${AOM_ROOT}/test/error_resilience_test.cc"
@@ -127,6 +126,7 @@
"${AOM_ROOT}/test/ec_test.cc"
"${AOM_ROOT}/test/ethread_test.cc"
"${AOM_ROOT}/test/film_grain_table_test.cc"
+ "${AOM_ROOT}/test/fwd_kf_test.cc"
"${AOM_ROOT}/test/sb_multipass_test.cc"
"${AOM_ROOT}/test/segment_binarization_sync.cc"
"${AOM_ROOT}/test/superframe_test.cc"