v4l2videodec: Fixes three H.264/HEVC ITU conformance tests
authorF. Duncanh <fduncanh@gmail.com>
Mon, 14 Nov 2022 00:19:41 +0000 (19:19 -0500)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 16 Nov 2022 10:00:03 +0000 (10:00 +0000)
Postpone the cleanup of any consecutive sequence of lost frames
which starts at frame 0, until frame 100 is dequeued from driver.

This allows fluster tests JVT/CVWP2_TOSHIBA_E, JVC/CVWP3_TOSHIBA_E
and HEVC/POC_A_Bossen_3 that sends out-of-order frames to successfully
complete  (e.g., test of Amphion vpu driver).

Fixes #1569

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3398>

subprojects/gst-plugins-good/sys/v4l2/gstv4l2videodec.c

index 9f6fa7b..2a110e5 100644 (file)
@@ -675,11 +675,9 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
   GstVideoCodecFrame *frame;
   GstBuffer *buffer = NULL;
   GstFlowReturn ret;
-  gint capture_configuration_change;
 
   GST_VIDEO_DECODER_STREAM_LOCK (decoder);
-  if ((capture_configuration_change =
-          g_atomic_int_get (&self->capture_configuration_change))) {
+  if (g_atomic_int_get (&self->capture_configuration_change)) {
     gst_v4l2_object_stop (self->v4l2capture);
     ret = gst_v4l2_video_dec_setup_capture (decoder);
     if (ret != GST_FLOW_OK) {
@@ -761,36 +759,38 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
     while ((oldest_frame = gst_video_decoder_get_oldest_frame (decoder)) &&
         check_system_frame_number_too_old (frame->system_frame_number,
             oldest_frame->system_frame_number)) {
-      gst_video_decoder_drop_frame (decoder, oldest_frame);
-      oldest_frame = NULL;
-
-      if (!warned) {
-        g_warning ("%s: Too old frames, bug in decoder -- please file a bug",
-            GST_ELEMENT_NAME (decoder));
-        warned = TRUE;
-      }
-    }
-
-    /* If the initial frame triggered a Caps renegotiation, but with no actual change in 
-     * resolution, already-correctly-decoded frames may incorrectly be dropped by the driver.
-     * This has been observed to occur in at least one driver.  These frames will never dequeue.
-     * As a workaround, drop all pending frames older than the current frame now. */
-    if (capture_configuration_change && oldest_frame
-        && oldest_frame->system_frame_number == 0
-        && frame->system_frame_number) {
-      gint counter = 0;
-      while (oldest_frame) {
-        counter++;
+      if (oldest_frame->system_frame_number > 0) {
         gst_video_decoder_drop_frame (decoder, oldest_frame);
-        oldest_frame = gst_video_decoder_get_oldest_frame (decoder);
-        if (oldest_frame->system_frame_number == frame->system_frame_number) {
-          gst_video_codec_frame_unref (oldest_frame);
-          oldest_frame = NULL;
+        oldest_frame = NULL;
+
+        if (!warned) {
+          g_warning ("%s: Too old frames, bug in decoder -- please file a bug",
+              GST_ELEMENT_NAME (decoder));
+          warned = TRUE;
+        }
+      } else {
+        /* special treatment when oldest_frame->system_frame_number = 0:
+         * if a consecutive sequence 0, 1, 2,..., n < frame->system_frame_number
+         * is pending, drop them all at this time. (This has been seen to occur
+         * as a driver bug when the initial frame triggered a Caps re-negotiation,
+         * and the driver dropped these frames) */
+        guint32 counter = 0;
+        while (oldest_frame) {
+          gst_video_decoder_drop_frame (decoder, oldest_frame);
+          counter++;
+          oldest_frame = gst_video_decoder_get_oldest_frame (decoder);
+          if (oldest_frame &&
+              (oldest_frame->system_frame_number > counter ||
+                  oldest_frame->system_frame_number >=
+                  frame->system_frame_number)) {
+            gst_video_codec_frame_unref (oldest_frame);
+            oldest_frame = NULL;
+          }
         }
+        g_warning
+            ("%s: %i initial frames were not dequeued: bug in decoder -- please file a bug",
+            GST_ELEMENT_NAME (decoder), counter);
       }
-      g_warning
-          ("%s: %i initial frames before frame %u were not dequeued: bug in decoder -- please file a bug",
-          GST_ELEMENT_NAME (decoder), counter, frame->system_frame_number);
     }
     if (oldest_frame)
       gst_video_codec_frame_unref (oldest_frame);