goom: post QoS messages when dropping frames due to QoS
authorTim-Philipp Müller <tim@centricular.com>
Sun, 2 Nov 2014 19:29:52 +0000 (19:29 +0000)
committerTim-Philipp Müller <tim@centricular.com>
Sun, 2 Nov 2014 19:31:01 +0000 (19:31 +0000)
gst/goom/gstgoom.c
gst/goom/gstgoom.h

index 76b4ee8..b22531a 100644 (file)
@@ -97,6 +97,7 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
 
 
 static void gst_goom_finalize (GObject * object);
+static void gst_goom_reset (GstGoom * goom);
 
 static GstStateChangeReturn gst_goom_change_state (GstElement * element,
     GstStateChange transition);
@@ -168,6 +169,8 @@ gst_goom_init (GstGoom * goom)
   goom->duration = 0;
 
   goom->plugin = goom_init (goom->width, goom->height);
+
+  gst_goom_reset (goom);
 }
 
 static void
@@ -193,8 +196,11 @@ gst_goom_reset (GstGoom * goom)
 
   GST_OBJECT_LOCK (goom);
   goom->proportion = 1.0;
-  goom->earliest_time = -1;
+  goom->earliest_time = GST_CLOCK_TIME_NONE;
   GST_OBJECT_UNLOCK (goom);
+
+  goom->dropped = 0;
+  goom->processed = 0;
 }
 
 static gboolean
@@ -547,26 +553,44 @@ gst_goom_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
       timestamp += gst_util_uint64_scale_int (dist, GST_SECOND, goom->rate);
     }
 
+    /* check for QoS, don't compute buffers that are known to be late */
     if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
+      GstClockTime earliest_time;
+      gdouble proportion;
       gint64 qostime;
-      gboolean need_skip;
 
       qostime = gst_segment_to_running_time (&goom->segment, GST_FORMAT_TIME,
           timestamp) + goom->duration;
 
       GST_OBJECT_LOCK (goom);
-      /* check for QoS, don't compute buffers that are known to be late */
-      need_skip = goom->earliest_time != -1 && qostime <= goom->earliest_time;
+      earliest_time = goom->earliest_time;
+      proportion = goom->proportion;
       GST_OBJECT_UNLOCK (goom);
 
-      if (need_skip) {
+      if (GST_CLOCK_TIME_IS_VALID (earliest_time) && qostime <= earliest_time) {
+        GstClockTime stream_time, jitter;
+        GstMessage *qos_msg;
+
         GST_WARNING_OBJECT (goom,
             "QoS: skip ts: %" GST_TIME_FORMAT ", earliest: %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (qostime), GST_TIME_ARGS (goom->earliest_time));
+            GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
+
+        goom->dropped++;
+        stream_time = gst_segment_to_stream_time (&goom->segment,
+            GST_FORMAT_TIME, timestamp);
+        jitter = GST_CLOCK_DIFF (qostime, earliest_time);
+        qos_msg = gst_message_new_qos (GST_OBJECT (goom), FALSE, qostime,
+            stream_time, timestamp, GST_BUFFER_DURATION (buffer));
+        gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000);
+        gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS,
+            goom->processed, goom->dropped);
+        gst_element_post_message (GST_ELEMENT (goom), qos_msg);
         goto skip;
       }
     }
 
+    goom->processed++;
+
     /* get next GOOM_SAMPLES, we have at least this amount of samples */
     data =
         (const guint16 *) gst_adapter_map (goom->adapter,
index 331e6ab..5d1b82a 100644 (file)
@@ -59,6 +59,9 @@ struct _GstGoom
   guint outsize;
   GstBufferPool *pool;
 
+  guint dropped;        /* frames dropped / not dropped */
+  guint processed;
+
   /* samples per frame */
   guint spf;
   /* bytes per frame */