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