[Telepathy-commits] [telepathy-stream-engine/master] Add text overlay with the current FPS

Olivier Crête olivier.crete at collabora.co.uk
Mon Mar 23 17:58:14 PDT 2009


---
 src/videosink.c |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/src/videosink.c b/src/videosink.c
index 032a1a3..91c6bc6 100644
--- a/src/videosink.c
+++ b/src/videosink.c
@@ -49,6 +49,10 @@ struct _TpStreamEngineVideoSinkPrivate
 
   gulong delete_event_handler_id;
   gulong embedded_handler_id;
+
+  GstClockTime last_timestamp;
+  gdouble framerate;
+  GstElement *textoverlay;
 };
 
 /* properties */
@@ -79,12 +83,69 @@ tp_stream_engine_video_sink_init (TpStreamEngineVideoSink *self)
       TP_STREAM_ENGINE_TYPE_VIDEO_SINK, TpStreamEngineVideoSinkPrivate);
 
   self->priv = priv;
+
+  priv->last_timestamp = GST_CLOCK_TIME_NONE;
 }
 
 
+static gboolean
+fps_qos_probe (GstPad *pad, GstEvent *event, gpointer user_data)
+{
+  TpStreamEngineVideoSink *self = TP_STREAM_ENGINE_VIDEO_SINK (user_data);
+  gdouble proportion;
+  GstClockTimeDiff diff;
+  GstClockTime timestamp;
+
+  if (GST_EVENT_TYPE (event) != GST_EVENT_QOS)
+    return TRUE;
+
+  gst_event_parse_qos (event, &proportion, &diff, &timestamp);
+
+  /* Ignore late buffers */
+  if (diff > 0)
+    return TRUE;
+
+  if (GST_CLOCK_TIME_IS_VALID (self->priv->last_timestamp))
+    {
+      GstClockTimeDiff diff = GST_CLOCK_DIFF(self->priv->last_timestamp,
+          timestamp);
+      gdouble diffs;
+
+      if (diff > GST_SECOND)
+        diff = GST_SECOND;
+
+      diffs = (gdouble)diff / (gdouble)GST_SECOND;
+      if (self->priv->framerate != 0)
+        {
+        self->priv->framerate = (1.0/diffs)*(diffs) + self->priv->framerate*(1-diffs);
+
+        if (self->priv->textoverlay)
+          {
+            gchar *str = g_strdup_printf ("FPS: %f", self->priv->framerate);
+            g_object_set (self->priv->textoverlay, "text", str, NULL);
+            g_free (str);
+          }
+        else
+          {
+            g_debug("Last diff: %lld diffs: %f Instant fps: %f"
+                " averaged over 1s: %f\n", diff, diffs, (1.0/diffs),
+                self->priv->framerate);
+          }
+        }
+      else
+        {
+          self->priv->framerate = 1.0/diffs;
+        }
+    }
+
+  self->priv->last_timestamp = timestamp;
+
+  return TRUE;
+}
+
 
 static GstElement *
-make_video_sink (gboolean is_preview)
+make_video_sink (TpStreamEngineVideoSink *self, gboolean is_preview)
 {
   const gchar *videosink_name;
   GstElement *sink = NULL;
@@ -129,6 +190,32 @@ make_video_sink (gboolean is_preview)
       return NULL;
     }
 
+  if (g_getenv ("STREAM_ENGINE_FPS") &&
+      !strcmp (g_getenv ("STREAM_ENGINE_FPS"), "overlay"))
+    {
+      tmp = gst_element_factory_make ("textoverlay", NULL);
+
+      if (tmp != NULL)
+        {
+          self->priv->textoverlay = tmp;
+          g_debug ("linking textoverlay");
+          if (!gst_bin_add (GST_BIN (bin), tmp))
+            {
+              g_warning ("Could not add textoverlay to the source bin");
+              gst_object_unref (tmp);
+              gst_object_unref (bin);
+              return NULL;
+            }
+          if (!gst_element_link (tmp, sink))
+            {
+              g_warning ("Could not link sink and textoverlay elements");
+              gst_object_unref (bin);
+              return NULL;
+            }
+          sink = tmp;
+        }
+    }
+
   tmp = gst_element_factory_make ("videoscale", NULL);
   if (tmp != NULL)
     {
@@ -181,6 +268,9 @@ make_video_sink (gboolean is_preview)
       return NULL;
     }
 
+  if (g_getenv ("STREAM_ENGINE_FPS"))
+    gst_pad_add_event_probe (pad, G_CALLBACK (fps_qos_probe), self);
+
   ghostpad = gst_ghost_pad_new ("sink", pad);
   if (!gst_element_add_pad (bin, ghostpad))
     {
@@ -229,7 +319,7 @@ tp_stream_engine_video_sink_constructor (GType type,
 
   self = (TpStreamEngineVideoSink *) obj;
 
-  self->priv->sink = make_video_sink (self->priv->is_preview);
+  self->priv->sink = make_video_sink (self, self->priv->is_preview);
 
   if (self->priv->sink)
     gst_object_ref (self->priv->sink);
-- 
1.5.6.5




More information about the telepathy-commits mailing list