]> git.0d.be Git - empathy.git/blobdiff - src/empathy-video-src.c
Updated Greek translation
[empathy.git] / src / empathy-video-src.c
index ca8370d82b66ce45592529ec95c0665043f5813a..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,6 +51,12 @@ struct _EmpathyGstVideoSrcPrivate
   GstElement *src;
   /* Element implementing a ColorBalance interface */
   GstElement *balance;
+  /* Elements for resolution and framerate adjustment */
+  GstElement *capsfilter;
+  GstElement *videorate;
+  guint width;
+  guint height;
+  guint framerate;
 };
 
 #define EMPATHY_GST_VIDEO_SRC_GET_PRIVATE(o) \
@@ -105,6 +108,16 @@ error:
   return NULL;
 }
 
+static GstPadProbeReturn
+empathy_video_src_drop_eos (GstPad *pad,
+  GstPadProbeInfo *info,
+  gpointer user_data)
+{
+  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
 empathy_video_src_init (EmpathyGstVideoSrc *obj)
@@ -116,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);
@@ -129,29 +142,49 @@ empathy_video_src_init (EmpathyGstVideoSrc *obj)
   /* we need to save our source to priv->src */
   priv->src = element;
 
-  /* videomaxrate is optional as it's part of gst-plugins-bad. So don't
-   * fail if it doesn't exist. */
+  /* 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_probe (src, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+    empathy_video_src_drop_eos, NULL, NULL);
+
+  gst_object_unref (src);
+
+  /* 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->videorate = element;
+      g_object_set (G_OBJECT (element),
+        "drop-only", TRUE,
+        "average-period", GST_SECOND/2,
+        NULL);
     }
   else
     {
-      gst_caps_set_simple (caps,
-        "framerate", GST_TYPE_FRACTION, 15, 1,
-        NULL);
+      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,
+      "framerate", GST_TYPE_FRACTION_RANGE, 1, 1, 30, 1,
+      NULL);
+
   str = gst_caps_to_string (caps);
   DEBUG ("Current video src caps are : %s", str);
   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)
@@ -162,6 +195,7 @@ empathy_video_src_init (EmpathyGstVideoSrc *obj)
     g_error (
       "Failed to add \"capsfilter\" (gstreamer core elements missing?)");
 
+  priv->capsfilter = element;
   g_object_set (G_OBJECT (element), "caps", caps, NULL);
 
 
@@ -393,3 +427,60 @@ empathy_video_src_dup_device (EmpathyGstVideoSrc *self)
 
   return device;
 }
+
+void
+empathy_video_src_set_framerate (GstElement *src,
+    guint framerate)
+{
+  EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (src);
+
+  if (priv->videorate)
+    {
+      g_object_set (G_OBJECT (priv->videorate), "max-rate", framerate, NULL);
+    }
+}
+
+void
+empathy_video_src_set_resolution (GstElement *src,
+    guint width,
+    guint height)
+{
+  EmpathyGstVideoSrcPrivate *priv = EMPATHY_GST_VIDEO_SRC_GET_PRIVATE (src);
+  GstCaps *caps;
+  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);
+
+  gst_caps_set_simple (caps,
+      "width", G_TYPE_INT, width,
+      "height", G_TYPE_INT, height,
+      NULL);
+
+  g_object_set (priv->capsfilter, "caps", caps, NULL);
+  gst_caps_unref (caps);
+
+  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);
+}