]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-call-handler.c
Merge branch 'people-nearby-fake-group-613558'
[empathy.git] / libempathy / empathy-call-handler.c
index dd117eb999099cc624d0dcaf607305bc4e9951c9..3b7ce546c85901a105fb1889368c2b9e103c468f 100644 (file)
 #include <stdlib.h>
 
 #include <telepathy-glib/util.h>
+#include <telepathy-glib/interfaces.h>
 
 #include <telepathy-farsight/channel.h>
 #include <telepathy-farsight/stream.h>
 
-#include <gst/farsight/fs-element-added-notifier.h>
-
 #include "empathy-call-handler.h"
 #include "empathy-dispatcher.h"
 #include "empathy-marshal.h"
@@ -43,6 +42,7 @@ enum {
   SINK_PAD_ADDED,
   REQUEST_RESOURCE,
   CLOSED,
+  STREAM_CLOSED,
   LAST_SIGNAL
 };
 
@@ -65,7 +65,6 @@ typedef struct {
   TfChannel *tfchannel;
   gboolean initial_audio;
   gboolean initial_video;
-  FsElementAddedNotifier *fsnotifier;
 } EmpathyCallHandlerPriv;
 
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyCallHandler)
@@ -98,12 +97,6 @@ empathy_call_handler_dispose (GObject *object)
 
   priv->call = NULL;
 
-  if (priv->fsnotifier != NULL)
-    {
-      g_object_unref (priv->fsnotifier);
-    }
-  priv->fsnotifier = NULL;
-
   /* release any references held by the object here */
   if (G_OBJECT_CLASS (empathy_call_handler_parent_class)->dispose)
     G_OBJECT_CLASS (empathy_call_handler_parent_class)->dispose (object);
@@ -238,15 +231,15 @@ empathy_call_handler_class_init (EmpathyCallHandlerClass *klass)
   signals[SRC_PAD_ADDED] =
     g_signal_new ("src-pad-added", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
-      _empathy_marshal_VOID__OBJECT_UINT,
-      G_TYPE_NONE,
+      _empathy_marshal_BOOLEAN__OBJECT_UINT,
+      G_TYPE_BOOLEAN,
       2, GST_TYPE_PAD, G_TYPE_UINT);
 
   signals[SINK_PAD_ADDED] =
     g_signal_new ("sink-pad-added", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
-      _empathy_marshal_VOID__OBJECT_UINT,
-      G_TYPE_NONE,
+      _empathy_marshal_BOOLEAN__OBJECT_UINT,
+      G_TYPE_BOOLEAN,
       2, GST_TYPE_PAD, G_TYPE_UINT);
 
   signals[REQUEST_RESOURCE] =
@@ -262,6 +255,12 @@ empathy_call_handler_class_init (EmpathyCallHandlerClass *klass)
       g_cclosure_marshal_VOID__VOID,
       G_TYPE_NONE,
       0);
+
+  signals[STREAM_CLOSED] =
+    g_signal_new ("stream-closed", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+      g_cclosure_marshal_VOID__OBJECT,
+      G_TYPE_NONE, 1, TF_TYPE_STREAM);
 }
 
 /**
@@ -321,52 +320,25 @@ empathy_call_handler_bus_message (EmpathyCallHandler *handler,
   tf_channel_bus_message (priv->tfchannel, message);
 }
 
-static void
-conference_element_added (FsElementAddedNotifier *notifier,
-    GstBin *bin,
-    GstElement *element,
-    gpointer user_data)
-{
-  GstElementFactory *factory;
-  const gchar *name;
-
-  factory = gst_element_get_factory (element);
-  name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
-
-  if (!tp_strdiff (name, "x264enc"))
-    {
-      /* Ensure that the encoder creates the baseline profile */
-      g_object_set (element,
-          "byte-stream", TRUE,
-          "bframes", 0,
-          "b-adapt", FALSE,
-          "cabac", FALSE,
-          "dct8x8", FALSE,
-          NULL);
-    }
-  else if (!tp_strdiff (name, "gstrtpbin"))
-    {
-      /* Lower the jitterbuffer latency to make it more suitable for video
-       * conferencing */
-      g_object_set (element, "latency", 100, NULL);
-    }
-}
-
 static void
 empathy_call_handler_tf_channel_session_created_cb (TfChannel *tfchannel,
   FsConference *conference, FsParticipant *participant,
   EmpathyCallHandler *self)
 {
-  EmpathyCallHandlerPriv *priv = GET_PRIV (self);
+  g_signal_emit (G_OBJECT (self), signals[CONFERENCE_ADDED], 0,
+    GST_ELEMENT (conference));
+}
 
-  priv->fsnotifier = fs_element_added_notifier_new ();
-  fs_element_added_notifier_add (priv->fsnotifier, GST_BIN (conference));
+static gboolean
+src_pad_added_error_idle (gpointer data)
+{
+  TfStream *stream = data;
 
-  g_signal_connect (priv->fsnotifier, "element-added",
-    G_CALLBACK (conference_element_added), NULL);
+  tf_stream_error (stream, TP_MEDIA_STREAM_ERROR_MEDIA_ERROR,
+      "Could not link sink");
+  g_object_unref (stream);
 
-  g_signal_emit (G_OBJECT (self), signals[CONFERENCE_ADDED], 0,
-    GST_ELEMENT (conference));
+  return FALSE;
 }
 
 static void
@@ -374,11 +346,15 @@ empathy_call_handler_tf_stream_src_pad_added_cb (TfStream *stream,
   GstPad *pad, FsCodec *codec, EmpathyCallHandler  *handler)
 {
   guint media_type;
+  gboolean retval;
 
   g_object_get (stream, "media-type", &media_type, NULL);
 
   g_signal_emit (G_OBJECT (handler), signals[SRC_PAD_ADDED], 0,
-    pad, media_type);
+      pad, media_type, &retval);
+
+  if (!retval)
+    g_idle_add (src_pad_added_error_idle, g_object_ref (stream));
 }
 
 
@@ -397,24 +373,38 @@ empathy_call_handler_tf_stream_request_resource_cb (TfStream *stream,
   return ret;
 }
 
+static void
+empathy_call_handler_tf_stream_closed_cb (TfStream *stream,
+  EmpathyCallHandler *handler)
+{
+  g_signal_emit (handler, signals[STREAM_CLOSED], 0, stream);
+}
+
 static void
 empathy_call_handler_tf_channel_stream_created_cb (TfChannel *tfchannel,
   TfStream *stream, EmpathyCallHandler *handler)
 {
   guint media_type;
   GstPad *spad;
+  gboolean retval;
 
   g_signal_connect (stream, "src-pad-added",
       G_CALLBACK (empathy_call_handler_tf_stream_src_pad_added_cb), handler);
   g_signal_connect (stream, "request-resource",
       G_CALLBACK (empathy_call_handler_tf_stream_request_resource_cb),
         handler);
+  g_signal_connect (stream, "closed",
+      G_CALLBACK (empathy_call_handler_tf_stream_closed_cb), handler);
 
   g_object_get (stream, "media-type", &media_type,
     "sink-pad", &spad, NULL);
 
   g_signal_emit (G_OBJECT (handler), signals[SINK_PAD_ADDED], 0,
-    spad, media_type);
+      spad, media_type, &retval);
+
+ if (!retval)
+      tf_stream_error (stream, TP_MEDIA_STREAM_ERROR_MEDIA_ERROR,
+          "Could not link source");
 
   gst_object_unref (spad);
 }
@@ -426,54 +416,25 @@ empathy_call_handler_tf_channel_closed_cb (TfChannel *tfchannel,
   g_signal_emit (G_OBJECT (handler), signals[CLOSED], 0);
 }
 
-static GList *
-empathy_call_handler_tf_channel_codec_config_get_defaults (FsCodec *codecs)
-{
-  GList *l = NULL;
-  int i;
-
-  for (i = 0; codecs[i].encoding_name != NULL; i++)
-      l = g_list_append (l, fs_codec_copy (codecs + i));
-
-  return l;
-}
-
 static GList *
 empathy_call_handler_tf_channel_codec_config_cb (TfChannel *channel,
   guint stream_id, FsMediaType media_type, guint direction, gpointer user_data)
 {
-  FsCodec audio_codecs[] = {
-    { FS_CODEC_ID_ANY, "SPEEX", FS_MEDIA_TYPE_AUDIO, 16000, },
-    { FS_CODEC_ID_ANY, "SPEEX", FS_MEDIA_TYPE_AUDIO, 8000, },
-
-    { FS_CODEC_ID_DISABLE, "DV",     FS_MEDIA_TYPE_AUDIO, },
-    { FS_CODEC_ID_DISABLE, "MPA",    FS_MEDIA_TYPE_AUDIO, },
-    { FS_CODEC_ID_DISABLE, "VORBIS", FS_MEDIA_TYPE_AUDIO, },
-    { FS_CODEC_ID_DISABLE, "MP3",    FS_MEDIA_TYPE_AUDIO, },
-    { 0, NULL, 0,}
-  };
-  FsCodec video_codecs[] = {
-    { FS_CODEC_ID_ANY, "H264",   FS_MEDIA_TYPE_VIDEO, },
-    { FS_CODEC_ID_ANY, "THEORA", FS_MEDIA_TYPE_VIDEO, },
-    { FS_CODEC_ID_ANY, "H263",   FS_MEDIA_TYPE_VIDEO, },
-
-    { FS_CODEC_ID_DISABLE, "DV",   FS_MEDIA_TYPE_VIDEO, },
-    { FS_CODEC_ID_DISABLE, "JPEG", FS_MEDIA_TYPE_VIDEO, },
-    { FS_CODEC_ID_DISABLE, "MPV",  FS_MEDIA_TYPE_VIDEO, },
-    { 0, NULL, 0}
-  };
-
-  switch (media_type)
+  gchar *filename = empathy_file_lookup ("codec-preferences", "data");
+  GList *codecs;
+  GError *error = NULL;
+
+  codecs = fs_codec_list_from_keyfile (filename, &error);
+  g_free (filename);
+
+  if (!codecs)
     {
-      case FS_MEDIA_TYPE_AUDIO:
-        return empathy_call_handler_tf_channel_codec_config_get_defaults
-          (audio_codecs);
-      case FS_MEDIA_TYPE_VIDEO:
-        return empathy_call_handler_tf_channel_codec_config_get_defaults
-          (video_codecs);
+      g_warning ("No codec-preferences file: %s",
+          error ? error->message : "No error message");
     }
+  g_clear_error (&error);
 
-  return NULL;
+  return codecs;
 }
 
 static void
@@ -515,6 +476,7 @@ empathy_call_handler_request_cb (EmpathyDispatchOperation *operation,
     empathy_dispatch_operation_get_channel_wrapper (operation));
 
   g_object_ref (priv->call);
+  g_object_notify (G_OBJECT (self), "tp-call");
 
   empathy_call_handler_start_tpfs (self);
 
@@ -614,4 +576,5 @@ empathy_call_handler_has_initial_video (EmpathyCallHandler *handler)
   EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
 
   return priv->initial_video;
-}
\ No newline at end of file
+}
+