]> git.0d.be Git - empathy.git/blobdiff - src/empathy-video-src.c
add an header bar to the main window
[empathy.git] / src / empathy-video-src.c
index e2842114fdc640ad84d1d18ef3d042ea39913849..41dea2377c3636a6f3f3952c5f621d0b726f2eef 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include "config.h"
+#include "empathy-video-src.h"
 
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <gst/interfaces/colorbalance.h>
+#include <gst/video/colorbalance.h>
 
 #define DEBUG_FLAG EMPATHY_DEBUG_VOIP
-#include <libempathy/empathy-debug.h>
-
-#include "empathy-video-src.h"
+#include "empathy-debug.h"
 
 G_DEFINE_TYPE(EmpathyGstVideoSrc, empathy_video_src, GST_TYPE_BIN)
 
@@ -54,12 +51,12 @@ struct _EmpathyGstVideoSrcPrivate
   GstElement *src;
   /* Element implementing a ColorBalance interface */
   GstElement *balance;
-  /* Element for resolution and framerate adjustment */
+  /* Elements for resolution and framerate adjustment */
   GstElement *capsfilter;
+  GstElement *videorate;
   guint width;
   guint height;
   guint framerate;
-  gboolean has_videomaxrate;
 };
 
 #define EMPATHY_GST_VIDEO_SRC_GET_PRIVATE(o) \
@@ -111,10 +108,15 @@ error:
   return NULL;
 }
 
-static gboolean
-empathy_video_src_drop_eos (GstPad *pad, GstEvent *event, gpointer user_data)
+static GstPadProbeReturn
+empathy_video_src_drop_eos (GstPad *pad,
+  GstPadProbeInfo *info,
+  gpointer user_data)
 {
-  return GST_EVENT_TYPE (event) != GST_EVENT_EOS;
+  if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_EVENT (info)) == GST_EVENT_EOS)
+    return GST_PAD_PROBE_DROP;
+
+  return GST_PAD_PROBE_OK;
 }
 
 static void
@@ -127,7 +129,7 @@ empathy_video_src_init (EmpathyGstVideoSrc *obj)
   gchar *str;
 
   /* allocate caps here, so we can update it by optional elements */
-  caps = gst_caps_new_simple ("video/x-raw-yuv",
+  caps = gst_caps_new_simple ("video/x-raw",
     "width", G_TYPE_INT, 320,
     "height", G_TYPE_INT, 240,
     NULL);
@@ -143,22 +145,33 @@ empathy_video_src_init (EmpathyGstVideoSrc *obj)
   /* Drop EOS events, so that our sinks don't get confused when we restart the
    * source (triggering an EOS) */
   src = gst_element_get_static_pad (element, "src");
-  gst_pad_add_event_probe (src, G_CALLBACK (empathy_video_src_drop_eos), NULL);
+
+  gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+    empathy_video_src_drop_eos, NULL, NULL);
+
   gst_object_unref (src);
 
-  /* videomaxrate is optional as it's part of gst-plugins-bad. So don't
-   * fail if it doesn't exist. */
+  /* videorate with the required properties optional as it needs a currently
+   * unreleased gst-plugins-base 0.10.36 */
   element_back = element;
-  if ((element = empathy_gst_add_to_bin (GST_BIN (obj),
-      element, "videomaxrate")) == NULL)
+  element = empathy_gst_add_to_bin (GST_BIN (obj), element, "videorate");
+
+  if (element != NULL && g_object_class_find_property (
+      G_OBJECT_GET_CLASS (element), "max-rate") != NULL)
     {
-      g_message ("Couldn't add \"videomaxrate\" (gst-plugins-bad missing?)");
-      element = element_back;
-      priv->has_videomaxrate = TRUE;
+      priv->videorate = element;
+      g_object_set (G_OBJECT (element),
+        "drop-only", TRUE,
+        "average-period", GST_SECOND/2,
+        NULL);
     }
   else
     {
-      priv->has_videomaxrate = TRUE;
+      g_message ("videorate missing or doesn't have max-rate property, not"
+        "doing dynamic framerate changes (Needs gst-plugins-base >= 0.10.36)");
+      /* Refcount owned by the bin */
+      gst_bin_remove (GST_BIN (obj), element);
+      element = element_back;
     }
 
   gst_caps_set_simple (caps,
@@ -170,8 +183,8 @@ empathy_video_src_init (EmpathyGstVideoSrc *obj)
   g_free (str);
 
   if ((element = empathy_gst_add_to_bin (GST_BIN (obj),
-      element, "ffmpegcolorspace")) == NULL)
-    g_error ("Failed to add \"ffmpegcolorspace\" (gst-plugins-base missing?)");
+      element, "videoconvert")) == NULL)
+    g_error ("Failed to add \"videoconvert\" (gst-plugins-base missing?)");
 
   if ((element = empathy_gst_add_to_bin (GST_BIN (obj),
       element, "videoscale")) == NULL)
@@ -420,20 +433,10 @@ empathy_video_src_set_framerate (GstElement *src,
     guint framerate)
 {
   EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (src);
-  GstCaps *caps;
 
-  if (priv->has_videomaxrate)
+  if (priv->videorate)
     {
-      g_return_if_fail (priv->capsfilter != NULL);
-
-      g_object_get (priv->capsfilter, "caps", &caps, NULL);
-      caps = gst_caps_make_writable (caps);
-
-      gst_caps_set_simple (caps,
-          "framerate", GST_TYPE_FRACTION, framerate, 1,
-          NULL);
-
-      g_object_set (priv->capsfilter, "caps", caps, NULL);
+      g_object_set (G_OBJECT (priv->videorate), "max-rate", framerate, NULL);
     }
 }
 
@@ -444,13 +447,20 @@ empathy_video_src_set_resolution (GstElement *src,
 {
   EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (src);
   GstCaps *caps;
-  GstClock *gst_clock;
+  GstPad *srcpad, *peer;
 
   g_return_if_fail (priv->capsfilter != NULL);
 
   gst_element_set_locked_state (priv->src, TRUE);
   gst_element_set_state (priv->src, GST_STATE_NULL);
 
+  srcpad = gst_element_get_static_pad (priv->src, "src");
+  peer = gst_pad_get_peer (srcpad);
+
+  /* Keep a ref as removing it from the bin will loose our reference */
+  gst_object_ref (priv->src);
+  gst_bin_remove (GST_BIN (src), priv->src);
+
   g_object_get (priv->capsfilter, "caps", &caps, NULL);
   caps = gst_caps_make_writable (caps);
 
@@ -460,14 +470,17 @@ empathy_video_src_set_resolution (GstElement *src,
       NULL);
 
   g_object_set (priv->capsfilter, "caps", caps, NULL);
+  gst_caps_unref (caps);
 
-  /* Reset clock an base time, this is require for videotestsrc and hopefully
-   * has no side effect */
-  gst_clock = gst_element_get_clock (src);
-  gst_element_set_clock (priv->src, gst_clock);
-  gst_element_set_base_time (priv->src, gst_element_get_base_time (src));
-  gst_object_unref (gst_clock);
+  gst_bin_add (GST_BIN (src), priv->src);
+  /* We as the bin own the source again, so drop the temporary ref */
+  gst_object_unref (priv->src);
+
+  gst_pad_link (srcpad, peer);
 
   gst_element_set_locked_state (priv->src, FALSE);
   gst_element_sync_state_with_parent (priv->src);
+
+  gst_object_unref (srcpad);
+  gst_object_unref (peer);
 }