ducatividdec: perform QoS after feeding the data to the hardware decoder
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Tue, 17 Jul 2012 10:11:08 +0000 (10:11 +0000)
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Tue, 17 Jul 2012 10:17:34 +0000 (10:17 +0000)
We do not want to drop frames before decoding them, or we will be unable
to recover a good image till next keyframe (or equivalent). Instead, we
always feed the data to the hardware decoder, and drop the decoder frames.

The "wait for a keyframe" code was split off the unrelated QoS code and
kept before feeding the data.

src/gstducatividdec.c

index afb36749a5c47048a6f095e1c685cd4c4beb2f01..04d23c8e74b2ba404b70e8b9a6e7f39c2230028a 100644 (file)
@@ -24,6 +24,8 @@
 #include "gstducatividdec.h"
 #include "gstducatibufferpriv.h"
 
+static gboolean gst_ducati_viddec_do_qos (GstDucatiVidDec * self, GstBuffer * buf);
+
 GST_BOILERPLATE (GstDucatiVidDec, gst_ducati_viddec, GstElement,
     GST_TYPE_ELEMENT);
 
@@ -299,6 +301,8 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush,
   gint i;
   GstDucatiVidDecClass *klass = GST_DUCATIVIDDEC_GET_CLASS (self);
   GstFlowReturn ret = GST_FLOW_OK;
+  gboolean decode;
+
   if (flow_ret)
     /* never leave flow_ret uninitialized */
     *flow_ret = GST_FLOW_OK;
@@ -463,6 +467,13 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush,
         gst_buffer_set_caps (outbuf, GST_PAD_CAPS (self->srcpad));
       }
 
+      decode = gst_ducati_viddec_do_qos (self, outbuf);
+      if (!decode) {
+        GST_DEBUG_OBJECT (self, "Output buffer too late, dropping");
+        gst_buffer_unref (outbuf);
+        continue;
+      }
+
       if (self->crop)
         gst_buffer_set_video_crop (outbuf, self->crop);
 
@@ -877,15 +888,6 @@ gst_ducati_viddec_do_qos (GstDucatiVidDec * self, GstBuffer * buf)
   GstDucatiVidDecClass *klass = GST_DUCATIVIDDEC_GET_CLASS (self);
   gint64 diff;
 
-  if (self->wait_keyframe) {
-    if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
-      GST_INFO_OBJECT (self, "skipping until the next keyframe");
-      return FALSE;
-    }
-
-    self->wait_keyframe = FALSE;
-  }
-
   timestamp = GST_BUFFER_TIMESTAMP (buf);
   if (self->segment.format != GST_FORMAT_TIME ||
       self->qos_earliest_time == GST_CLOCK_TIME_NONE)
@@ -940,7 +942,6 @@ gst_ducati_viddec_chain (GstPad * pad, GstBuffer * buf)
   Int32 err;
   GstBuffer *outbuf = NULL;
   GstCaps *outcaps = NULL;
-  gboolean decode;
 
   if (G_UNLIKELY (!self->engine)) {
     GST_ERROR_OBJECT (self, "no engine");
@@ -951,10 +952,14 @@ gst_ducati_viddec_chain (GstPad * pad, GstBuffer * buf)
   GST_DEBUG_OBJECT (self, "chain: %" GST_TIME_FORMAT " (%d bytes, flags %d)",
       GST_TIME_ARGS (ts), GST_BUFFER_SIZE (buf), GST_BUFFER_FLAGS (buf));
 
-  decode = gst_ducati_viddec_do_qos (self, buf);
-  if (!decode) {
-    gst_buffer_unref (buf);
-    return GST_FLOW_OK;
+  if (self->wait_keyframe) {
+    if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
+      GST_INFO_OBJECT (self, "skipping until the next keyframe");
+      gst_buffer_unref (buf);
+      return GST_FLOW_OK;
+    }
+
+    self->wait_keyframe = FALSE;
   }
 
   if (!self->need_out_buf)