Add S_FRAME presence test when altref is enabled
This patch modifies the existing unit test to check the
presence of S_FRAME configured using encoder option, when
altref is enabled. Also checks if all the s_frames are
introduced at altref frames.
Change-Id: I87c7fa551228755e91354ced4ea61effbcb74edc
diff --git a/aom/aomdx.h b/aom/aomdx.h
index 399c669..aa4f435 100644
--- a/aom/aomdx.h
+++ b/aom/aomdx.h
@@ -145,6 +145,18 @@
int is_reduced_still_picture_hdr;
} aom_still_picture_info;
+/*!\brief Structure to hold information about S_FRAME.
+ *
+ * Defines a structure to hold a information regarding S_FRAME
+ * and its position.
+ */
+typedef struct aom_s_frame_info {
+ /*! Indicates if current frame is S_FRAME */
+ int is_s_frame;
+ /*! Indicates if current S_FRAME is present at ALTREF frame*/
+ int is_s_frame_at_altref;
+} aom_s_frame_info;
+
/*!\brief Structure to hold information about screen content tools.
*
* Defines a structure to hold information about screen content
@@ -410,6 +422,10 @@
* decoded has show existing frame flag set.
*/
AOMD_GET_SHOW_EXISTING_FRAME_FLAG,
+
+ /*!\brief Codec control function to get the S_FRAME coding information
+ */
+ AOMD_GET_S_FRAME_INFO,
};
/*!\cond */
@@ -461,6 +477,9 @@
AOM_CTRL_USE_TYPE(AOMD_GET_SHOW_EXISTING_FRAME_FLAG, int *)
#define AOMD_CTRL_AOMD_GET_SHOW_EXISTING_FRAME_FLAG
+AOM_CTRL_USE_TYPE(AOMD_GET_S_FRAME_INFO, aom_s_frame_info *)
+#define AOMD_CTRL_AOMD_GET_S_FRAME_INFO
+
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 bc85f54..4ba411a 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -1128,6 +1128,26 @@
return AOM_CODEC_OK;
}
+static aom_codec_err_t ctrl_get_s_frame_info(aom_codec_alg_priv_t *ctx,
+ va_list args) {
+ aom_s_frame_info *const s_frame_info = va_arg(args, aom_s_frame_info *);
+ if (s_frame_info) {
+ if (ctx->frame_worker) {
+ AVxWorker *const worker = ctx->frame_worker;
+ FrameWorkerData *const frame_worker_data =
+ (FrameWorkerData *)worker->data1;
+ const AV1Decoder *pbi = frame_worker_data->pbi;
+ s_frame_info->is_s_frame = pbi->sframe_info.is_s_frame;
+ s_frame_info->is_s_frame_at_altref =
+ pbi->sframe_info.is_s_frame_at_altref;
+ return AOM_CODEC_OK;
+ } else {
+ return AOM_CODEC_ERROR;
+ }
+ }
+ 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 *);
@@ -1528,6 +1548,7 @@
{ AOMD_GET_STILL_PICTURE, ctrl_get_still_picture },
{ AOMD_GET_SB_SIZE, ctrl_get_sb_size },
{ AOMD_GET_SHOW_EXISTING_FRAME_FLAG, ctrl_get_show_existing_frame_flag },
+ { AOMD_GET_S_FRAME_INFO, ctrl_get_s_frame_info },
CTRL_MAP_END,
};
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 46bddc5..6638c1d 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -4440,6 +4440,9 @@
MACROBLOCKD *const xd = &pbi->dcb.xd;
BufferPool *const pool = cm->buffer_pool;
RefCntBuffer *const frame_bufs = pool->frame_bufs;
+ aom_s_frame_info *sframe_info = &pbi->sframe_info;
+ sframe_info->is_s_frame = 0;
+ sframe_info->is_s_frame_at_altref = 0;
if (!pbi->sequence_header_ready) {
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
@@ -4548,6 +4551,10 @@
if (cm->show_frame == 0) pbi->is_arf_frame_present = 1;
if (cm->show_frame == 0 && cm->current_frame.frame_type == KEY_FRAME)
pbi->is_fwd_kf_present = 1;
+ if (cm->current_frame.frame_type == S_FRAME) {
+ sframe_info->is_s_frame = 1;
+ sframe_info->is_s_frame_at_altref = cm->show_frame ? 0 : 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 98bf3cc..b20e9c1 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -329,6 +329,7 @@
int is_fwd_kf_present;
int is_arf_frame_present;
int num_tile_groups;
+ aom_s_frame_info sframe_info;
} AV1Decoder;
// Returns 0 on success. Sets pbi->common.error.error_code to a nonzero error
diff --git a/test/error_resilience_test.cc b/test/error_resilience_test.cc
index 5449303..f7e4287 100644
--- a/test/error_resilience_test.cc
+++ b/test/error_resilience_test.cc
@@ -465,14 +465,15 @@
// This class is used to check the presence of SFrame.
class SFramePresenceTestLarge
- : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode,
- aom_rc_mode>,
+ : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode,
+ aom_rc_mode, int>,
public ::libaom_test::EncoderTest {
protected:
SFramePresenceTestLarge()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
- rc_end_usage_(GET_PARAM(2)) {
+ rc_end_usage_(GET_PARAM(2)), enable_altref_(GET_PARAM(3)) {
is_sframe_present_ = 0;
+ is_sframe_position_violated_ = 0;
}
virtual ~SFramePresenceTestLarge() {}
@@ -487,6 +488,7 @@
cfg_.kf_max_dist = 60;
cfg_.g_lag_in_frames = 35;
cfg_.sframe_dist = 5;
+ if (enable_altref_) cfg_.sframe_mode = 2;
}
virtual bool DoDecode() const { return 1; }
@@ -495,21 +497,22 @@
::libaom_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(AOME_SET_CPUUSED, 5);
- encoder->Control(AOME_SET_ENABLEAUTOALTREF, 0);
+ encoder->Control(AOME_SET_ENABLEAUTOALTREF, enable_altref_);
}
}
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_sframe_present_ != 1 && AOM_CODEC_OK == res_dec) {
+ if (AOM_CODEC_OK == res_dec) {
aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
- int frame_flags = 0;
- AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_FRAME_FLAGS,
- &frame_flags);
- if ((frame_flags & AOM_FRAME_IS_SWITCH) ==
- static_cast<aom_codec_frame_flags_t>(AOM_FRAME_IS_SWITCH)) {
+ AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_S_FRAME_INFO,
+ &sframe_info);
+ if (sframe_info.is_s_frame) {
is_sframe_present_ = 1;
+ if (enable_altref_ && is_sframe_position_violated_ == 0 &&
+ sframe_info.is_s_frame_at_altref == 0)
+ is_sframe_position_violated_ = 1;
}
}
return AOM_CODEC_OK == res_dec;
@@ -518,18 +521,29 @@
::libaom_test::TestMode encoding_mode_;
aom_rc_mode rc_end_usage_;
int is_sframe_present_;
+ int is_sframe_position_violated_;
+ int enable_altref_;
+ aom_s_frame_info sframe_info;
};
TEST_P(SFramePresenceTestLarge, SFramePresenceTest) {
libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
cfg_.g_timebase.den, cfg_.g_timebase.num,
- 0, 10);
+ 0, 100);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_EQ(is_sframe_present_, 1);
+ if (enable_altref_) {
+ ASSERT_EQ(is_sframe_position_violated_, 0);
+ }
}
+/* TODO(anyone): Currently SFramePresenceTest fails when enable_altref_ = 1.
+ * Hence this configuration is not added. Add this configuration after the
+ * bug is fixed.
+ */
AV1_INSTANTIATE_TEST_SUITE(SFramePresenceTestLarge,
::testing::Values(::libaom_test::kOnePassGood,
::libaom_test::kTwoPassGood),
- ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ));
+ ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ),
+ ::testing::Values(0));
} // namespace