decoder: output decoded frames only once.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Mon, 30 Jun 2014 16:34:45 +0000 (18:34 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Mon, 30 Jun 2014 17:13:25 +0000 (19:13 +0200)
Make sure to output the decoded picture, and push the associated
GstVideoCodecFrame, only once. The frame fully represents what needs
to be output, included for interlaced streams. Otherwise, the base
GstVideoDecoder class would release the frame twice.

Anyway, the general process is to output decoded frames only when
they are complete. By complete, we mean a full frame was decoded or
both fields of a frame were decoded.

gst-libs/gst/vaapi/gstvaapidecoder_objects.c

index 5277fbc..edd9a62 100644 (file)
@@ -294,6 +294,17 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture)
   return TRUE;
 }
 
+/* Mark picture as output for internal purposes only. Don't push frame out */
+static void
+do_output_internal (GstVaapiPicture * picture)
+{
+  if (GST_VAAPI_PICTURE_IS_OUTPUT (picture))
+    return;
+
+  gst_video_codec_frame_clear (&picture->frame);
+  GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_OUTPUT);
+}
+
 static gboolean
 do_output (GstVaapiPicture * picture)
 {
@@ -350,10 +361,14 @@ gst_vaapi_picture_output (GstVaapiPicture * picture)
         break;
       if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD (parent_picture))
         break;
-      GST_VAAPI_PICTURE_FLAG_SET (parent_picture,
-          GST_VAAPI_PICTURE_FLAG_SKIPPED);
-      if (!do_output (parent_picture))
-        return FALSE;
+      if (parent_picture->frame == picture->frame)
+        do_output_internal (parent_picture);
+      else {
+        GST_VAAPI_PICTURE_FLAG_SET (parent_picture,
+            GST_VAAPI_PICTURE_FLAG_SKIPPED);
+        if (!do_output (parent_picture))
+          return FALSE;
+      }
     } while (0);
   }
   return do_output (picture);