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 } }