Fix on frame output order derivation
Fix on frame output order derivation (D014)
Fixes #221 on sometimes all frames are not encoded.
\-\> The issue was addressed by fixing the condition on writing OBUs associated with show_existing_frame and setting the value showable_frame correctly.
Fixes #213 on "PSNR Y" value (average) shown in summary differs between encoder log and VMAF log
\-\> The issue was addressed by inputting the same source image for PSNR calculation and with the fixes on #221.
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 03de32b..f0d06ab 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -6460,7 +6460,15 @@
}
#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
- if ((cm->show_existing_frame && !cm->features.error_resilient_mode)
+ // When enable_frame_output_order == 1, the OBU packet of show_existing_frame
+ // is not signaled for non-error-resilient mode.
+ // For error-resilienet mode, still an OBU is signaled.
+ if ((cm->seq_params.order_hint_info.enable_order_hint &&
+ cm->seq_params.enable_frame_output_order && cm->show_existing_frame &&
+ !cm->features.error_resilient_mode) ||
+ ((!cm->seq_params.order_hint_info.enable_order_hint ||
+ !cm->seq_params.enable_frame_output_order) &&
+ encode_show_existing_frame(cm))
#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
if (encode_show_existing_frame(cm)
#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 2683de9..06809d7 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -863,6 +863,12 @@
source_buffer->metadata);
}
}
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ // when enable_frame_output_order == 1, show_existing mechanism is
+ // used for alt_ref in encoder side internally, but the OBU with
+ // show_existing_frame == 1 is not signaled in the bitstream.
+ if (cm->seq_params.enable_frame_output_order) show_existing_alt_ref = 1;
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
set_show_existing_alt_ref(&cpi->gf_group, apply_filtering,
oxcf->algo_cfg.enable_overlay,
show_existing_alt_ref);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index d2c5761..b7f30ab 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -1537,7 +1537,14 @@
PSNR_STATS psnr;
const uint32_t in_bit_depth = cpi->oxcf.input_cfg.input_bit_depth;
const uint32_t bit_depth = cpi->td.mb.e_mbd.bd;
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ // To match the PSNR results between encoder log and VMAF results,
+ // the same reference sources (unfiltered source) need to be used.
+ aom_calc_highbd_psnr(cpi->unfiltered_source, &cpi->common.cur_frame->buf,
+ &psnr,
+#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
aom_calc_highbd_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr,
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
bit_depth, in_bit_depth);
for (i = 0; i < 4; ++i) {
@@ -3929,7 +3936,11 @@
#endif
cpi->bytes += frame_bytes;
if (cm->show_frame) {
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ const YV12_BUFFER_CONFIG *orig = cpi->unfiltered_source;
+#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
const YV12_BUFFER_CONFIG *orig = cpi->source;
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
const YV12_BUFFER_CONFIG *recon = &cpi->common.cur_frame->buf;
double y, u, v, frame_all;
@@ -4029,9 +4040,11 @@
cpi->time_compress_data += aom_usec_timer_elapsed(&cmptimer);
#endif // CONFIG_INTERNAL_STATS
#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
- if (cpi->b_calculate_psnr) {
- if (cm->show_existing_frame ||
- (!is_stat_generation_stage(cpi) && cm->show_frame && *size > 0)) {
+ if (cpi->b_calculate_psnr && *size > 0) {
+ if ((cm->showable_frame && cm->seq_params.enable_frame_output_order) ||
+ (cm->show_existing_frame &&
+ !cm->seq_params.enable_frame_output_order) ||
+ (!is_stat_generation_stage(cpi) && cm->show_frame)) {
#else
// Note *size = 0 indicates a dropeed frame for which psnr is not calculated
if (cpi->b_calculate_psnr && *size > 0) {
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index 115c397..0e7fdce 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -1117,12 +1117,13 @@
// 1, showable_frame of the filtered frame is set to zero by default.
cpi->common.showable_frame =
(!cpi->oxcf.ref_frm_cfg.enable_frame_output_order &&
- num_frames_for_filtering == 1) ||
+ (num_frames_for_filtering == 1 || is_second_arf)) ||
+ cpi->oxcf.ref_frm_cfg.enable_frame_output_order ||
#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
- cpi->common.showable_frame =
- num_frames_for_filtering == 1 ||
+ cpi->common.showable_frame = num_frames_for_filtering == 1 ||
+ is_second_arf ||
#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
- is_second_arf || (cpi->oxcf.algo_cfg.enable_overlay == 0);
+ (cpi->oxcf.algo_cfg.enable_overlay == 0);
}
// Do filtering.
diff --git a/test/altref_test.cc b/test/altref_test.cc
index cf7ccd3..f5dfb4a 100644
--- a/test/altref_test.cc
+++ b/test/altref_test.cc
@@ -185,7 +185,11 @@
virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) {
(void)pkt;
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ frame_num_ += pkt->data.frame.frame_count;
+#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
++frame_num_;
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
}
const gfIntervalParam gf_interval_param_;
diff --git a/test/decode_perf_test.cc b/test/decode_perf_test.cc
index 5e5380e..4a85357 100644
--- a/test/decode_perf_test.cc
+++ b/test/decode_perf_test.cc
@@ -148,7 +148,11 @@
}
virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) {
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ out_frames_ += pkt->data.frame.frame_count;
+#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
++out_frames_;
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
// Write initial file header if first frame.
if (pkt->data.frame.pts == 0)
diff --git a/test/encode_test_driver.cc b/test/encode_test_driver.cc
index 2d191cd..74045a4 100644
--- a/test/encode_test_driver.cc
+++ b/test/encode_test_driver.cc
@@ -202,6 +202,10 @@
number_spatial_layers_ = GetNumSpatialLayers();
bool again;
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ unsigned int rec_frame_cnt = 0;
+ unsigned int failed_frame_cnt = 0;
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
for (again = true; again; video->Next()) {
again = (video->img() != NULL);
@@ -236,6 +240,9 @@
if (!HandleDecodeResult(res_dec, decoder.get())) break;
has_dxdata = true;
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ rec_frame_cnt += pkt->data.frame.frame_count;
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
}
ASSERT_GE(pkt->data.frame.pts, last_pts_);
if (sl == number_spatial_layers_) last_pts_ = pkt->data.frame.pts;
@@ -260,7 +267,22 @@
}
}
if (img_dec) DecompressedFrameHook(*img_dec, video->pts());
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ failed_frame_cnt = 0;
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
}
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ // Continue the encoding process, when an empty packet is received
+ // by skipping OBU with show_existing_frame == 1) and
+ // no longer input frames are remained due to lag_in frames.
+ // However the consecutive(10) packets are empty/failed, stop the
+ // encoding.
+ else if (rec_frame_cnt < video->limit() && !again &&
+ failed_frame_cnt < 10) {
+ again = true;
+ failed_frame_cnt++;
+ }
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
if (!Continue()) break;
} // Loop over spatial layers
}
diff --git a/test/error_resilience_test.cc b/test/error_resilience_test.cc
index cd9ca58..dc63465 100644
--- a/test/error_resilience_test.cc
+++ b/test/error_resilience_test.cc
@@ -82,6 +82,9 @@
if (video->frame() == 0) {
encoder->Control(AOME_SET_CPUUSED, kCpuUsed);
encoder->Control(AOME_SET_ENABLEAUTOALTREF, enable_altref_);
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ encoder->Control(AV1E_SET_FRAME_OUTPUT_ORDER_DERIVATION, 0);
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
}
frame_flags_ &= ~(AOM_EFLAG_NO_REF_FRAME_MVS | AOM_EFLAG_ERROR_RESILIENT |
AOM_EFLAG_NO_UPD_ALL | AOM_EFLAG_SET_S_FRAME |
@@ -502,6 +505,9 @@
::libaom_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(AOME_SET_CPUUSED, 5);
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ encoder->Control(AV1E_SET_FRAME_OUTPUT_ORDER_DERIVATION, 0);
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
if (rc_end_usage_ == AOM_Q) {
encoder->Control(AOME_SET_QP, 210);
}
diff --git a/test/horz_superres_test.cc b/test/horz_superres_test.cc
index b4d0222..be61740 100644
--- a/test/horz_superres_test.cc
+++ b/test/horz_superres_test.cc
@@ -54,7 +54,7 @@
const TestVideoParam kTestVideoVectors[] = {
{ "park_joy_90p_8_420.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 5, 0, 25.0,
- 44.5 },
+ 43.0 },
{ "park_joy_90p_10_444.y4m", AOM_IMG_FMT_I44416, AOM_BITS_10, 1, 5, 0, 28.0,
47.5 },
{ "screendata.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 4, 1, 16.0, 56.0 },
diff --git a/test/kf_test.cc b/test/kf_test.cc
index 1530afc..4a2910c 100644
--- a/test/kf_test.cc
+++ b/test/kf_test.cc
@@ -77,7 +77,7 @@
if (kf_dist_ != -1) {
#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
kf_dist_ += pkt->data.frame.frame_count;
-#else
+#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
(void)pkt;
++kf_dist_;
#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
@@ -180,7 +180,9 @@
is_kf_placement_violated_ = true;
}
}
+#if !CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
++frame_num_;
+#endif // !CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
}
return AOM_CODEC_OK == res_dec;
}
diff --git a/test/resize_test.cc b/test/resize_test.cc
index f4fc0ee..46a17a1 100644
--- a/test/resize_test.cc
+++ b/test/resize_test.cc
@@ -279,8 +279,11 @@
#if WRITE_COMPRESSED_STREAM
virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) {
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ out_frames_ += pkt->data.frame.frame_count;
+#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
++out_frames_;
-
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
// Write initial file header if first frame.
if (pkt->data.frame.pts == 0) write_ivf_file_header(&cfg_, 0, outfile_);
@@ -372,6 +375,9 @@
if (video->frame() == 0) {
encoder->Control(AOME_SET_CPUUSED, cpu_used_);
encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ encoder->Control(AV1E_SET_FRAME_OUTPUT_ORDER_DERIVATION, 0);
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
}
}
diff --git a/test/subgop_test.cc b/test/subgop_test.cc
index 78d4fae..be62bd3 100644
--- a/test/subgop_test.cc
+++ b/test/subgop_test.cc
@@ -614,7 +614,7 @@
virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) {
#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
frame_num_in_subgop_ += pkt->data.frame.frame_count;
-#else
+#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
(void)pkt;
++frame_num_in_subgop_;
#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
@@ -1001,7 +1001,7 @@
virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) {
#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
frame_num_in_subgop_ += pkt->data.frame.frame_count;
-#else
+#else // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
(void)pkt;
++frame_num_in_subgop_;
#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
diff --git a/test/tile_config_test.cc b/test/tile_config_test.cc
index 2bed6cb..8588c53 100644
--- a/test/tile_config_test.cc
+++ b/test/tile_config_test.cc
@@ -324,6 +324,9 @@
tile_group_config_params_.num_tile_cols);
encoder->Control(AV1E_SET_TILE_ROWS,
tile_group_config_params_.num_tile_rows);
+#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
+ encoder->Control(AV1E_SET_FRAME_OUTPUT_ORDER_DERIVATION, 0);
+#endif // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
}
}