[farsight2/master] Create pipelines just in time

Olivier Crête olivier.crete at collabora.co.uk
Tue Jul 14 09:50:45 PDT 2009


---
 gst/fsmsnconference/fs-msn-stream.c |  460 +++++++++++++----------------------
 1 files changed, 171 insertions(+), 289 deletions(-)

diff --git a/gst/fsmsnconference/fs-msn-stream.c b/gst/fsmsnconference/fs-msn-stream.c
index 483c103..8f3247a 100644
--- a/gst/fsmsnconference/fs-msn-stream.c
+++ b/gst/fsmsnconference/fs-msn-stream.c
@@ -70,15 +70,15 @@ struct _FsMsnStreamPrivate
   FsMsnParticipant *participant;
   FsStreamDirection direction;
   FsMsnConference *conference;
-  GstElement *media_fd_src;
-  GstElement *media_fd_sink;
   GstElement *session_valve;
-  GstPad *sink_pad,*src_pad;
+  GstPad *src_pad;
   FsMsnConnection *connection;
 
-  GError *construction_error;
+  FsStreamDirection orig_direction;
+
+  GstElement *codecbin;
 
-  gboolean disposed;
+  GError *construction_error;
 };
 
 
@@ -115,7 +115,6 @@ static void _new_local_candidate (
 
 
 
-
 static GObjectClass *parent_class = NULL;
 
 static void
@@ -164,11 +163,11 @@ fs_msn_stream_init (FsMsnStream *self)
   /* member init */
   self->priv = FS_MSN_STREAM_GET_PRIVATE (self);
 
-  self->priv->disposed = FALSE;
   self->priv->session = NULL;
   self->priv->participant = NULL;
 
   self->priv->direction = FS_DIRECTION_NONE;
+  self->priv->orig_direction = FS_DIRECTION_NONE;
 
 }
 
@@ -177,12 +176,6 @@ fs_msn_stream_dispose (GObject *object)
 {
   FsMsnStream *self = FS_MSN_STREAM (object);
 
-  if (self->priv->disposed)
-  {
-    /* If dispose did already run, return. */
-    return;
-  }
-
   if (self->priv->participant)
   {
     g_object_unref (self->priv->participant);
@@ -195,9 +188,6 @@ fs_msn_stream_dispose (GObject *object)
     self->priv->session = NULL;
   }
 
-  /* Make sure dispose does not run twice. */
-  self->priv->disposed = TRUE;
-
   parent_class->dispose (object);
 }
 
@@ -253,6 +243,32 @@ fs_msn_stream_set_property (GObject *object,
       self->priv->participant = FS_MSN_PARTICIPANT (g_value_dup_object (value));
       break;
     case PROP_DIRECTION:
+      if (self->priv->orig_direction == FS_DIRECTION_NONE)
+      {
+        self->priv->orig_direction = g_value_get_flags (value);
+        self->priv->direction = g_value_get_flags (value);
+        break;
+      }
+
+      if (g_value_get_flags (value) != self->priv->direction)
+      {
+        self->priv->direction =
+          g_value_get_flags (value) & self->priv->orig_direction;
+
+        /*
+         * Start stop the valves to control the direction
+         *
+        if (self->priv->direction == FS_DIRECTION_NONE)
+        {
+        }
+        else if (self->priv->direction == FS_DIRECTION_SEND)
+        {
+        }
+        else if (self->priv->direction == FS_DIRECTION_RECV)
+        {
+        }
+        */
+      }
       self->priv->direction = g_value_get_flags (value);
       break;
     case PROP_CONFERENCE:
@@ -272,266 +288,37 @@ fs_msn_stream_constructed (GObject *object)
 
   if (self->priv->direction == FS_DIRECTION_SEND)
   {
-    GstElement *mimenc;
-    GstElement *ffmpegcolorspace;
-    GstElement *queue;
-
-    ffmpegcolorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
-
-    if (!ffmpegcolorspace)
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not create the ffmpegcolorspace element");
-      return;
-    }
-
-    if (!gst_bin_add (GST_BIN (self->priv->conference), ffmpegcolorspace))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not add the ffmpegcolorspace element to the FsMsnConference");
-      gst_object_unref (ffmpegcolorspace);
-      return;
-    }
-
-    if (!gst_element_sync_state_with_parent (ffmpegcolorspace))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not sync state for ffmpegcolorspace element");
-      return;
-    }
+    GstElementFactory *fact = NULL;
 
-
-    queue = gst_element_factory_make ("queue", NULL);
-
-    if (!queue)
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not create the queue element");
-      return;
-    }
-
-    if (!gst_bin_add (GST_BIN (self->priv->conference), queue))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not add the queue element to the FsMsnConference");
-      gst_object_unref (queue);
-      return;
-    }
-
-    if (!gst_element_sync_state_with_parent (queue))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not sync state for queue element");
-      return;
-    }
-
-    mimenc = gst_element_factory_make ("mimenc", "send_mim_enc");
-
-    if (!mimenc)
+    fact = gst_element_factory_find ("mimenc");
+    if (fact)
     {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not create the mimenc element");
-      return;
+      gst_object_unref (fact);
     }
-
-    if (!gst_bin_add (GST_BIN (self->priv->conference), mimenc))
+    else
     {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not add the mimenc element to the FsMsnConference");
-      gst_object_unref (mimenc);
+      g_set_error (&self->priv->construction_error,
+          FS_ERROR, FS_ERROR_CONSTRUCTION,
+          "mimenc missing");
       return;
     }
-
-    if (!gst_element_sync_state_with_parent (mimenc))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not set state for mimenc element");
-      return;
-    }
-
-    self->priv->media_fd_sink = gst_element_factory_make ("fdsink",
-        "send_fd_sink");
-
-    if (!self->priv->media_fd_sink)
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not create the media_fd_sink element");
-      return;
-    }
-
-    if (!gst_bin_add (GST_BIN (self->priv->conference),
-            self->priv->media_fd_sink))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not add the media_fd_sink element to the FsMsnConference");
-      gst_object_unref (self->priv->media_fd_sink);
-      return;
-    }
-
-    if (!gst_element_set_locked_state(self->priv->media_fd_sink,TRUE))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not lock state of media_fd_sink element");
-      return;
-    }
-
-
-    gst_element_link_many(queue, ffmpegcolorspace, mimenc,
-        self->priv->media_fd_sink, NULL);
-
-    self->priv->sink_pad = gst_element_get_static_pad (queue, "sink");
-
   }
   else if (self->priv->direction == FS_DIRECTION_RECV)
   {
+   GstElementFactory *fact = NULL;
 
-    GstElement *mimdec;
-    GstElement *queue;
-    GstElement *ffmpegcolorspace;
-    GstPad *tmp_src_pad;
-
-    self->priv->media_fd_src = gst_element_factory_make ("fdsrc",
-        "recv_fd_src");
-
-    if (!self->priv->media_fd_src)
+    fact = gst_element_factory_find ("mimdec");
+    if (fact)
     {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not create the media_fd_src element");
-      return;
+      gst_object_unref (fact);
     }
-
-    g_object_set (G_OBJECT(self->priv->media_fd_src), "blocksize", 512, NULL);
-    if (!gst_bin_add (GST_BIN (self->priv->conference),
-            self->priv->media_fd_src))
+    else
     {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not add the media_fd_src element to the FsMsnConference");
-      gst_object_unref (self->priv->media_fd_src);
+      g_set_error (&self->priv->construction_error,
+          FS_ERROR, FS_ERROR_CONSTRUCTION,
+          "mimdec missing");
       return;
     }
-
-    if (!gst_element_set_locked_state(self->priv->media_fd_src,TRUE))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not lock state of media_fd_src element");
-      return;
-    }
-
-
-    mimdec = gst_element_factory_make ("mimdec", "recv_mim_dec");
-
-    if (!mimdec)
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not create the mimdec element");
-      return;
-    }
-
-    if (!gst_bin_add (GST_BIN (self->priv->conference), mimdec))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not add the mimdec element to the FsMsnConference");
-      gst_object_unref (mimdec);
-      return;
-    }
-    if (!gst_element_sync_state_with_parent  (mimdec))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not sync state with parent for mimdec element");
-      return;
-    }
-
-    queue = gst_element_factory_make ("queue", NULL);
-
-    if (!queue)
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not create the queue element");
-      return;
-    }
-
-    if (!gst_bin_add (GST_BIN (self->priv->conference), queue))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not add the queue element to the FsMsnConference");
-      gst_object_unref (queue);
-      return;
-    }
-
-    if (!gst_element_sync_state_with_parent  (queue))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not sync state with parent for queue element");
-      return;
-    }
-
-    ffmpegcolorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
-
-    if (!ffmpegcolorspace)
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not create the ffmpegcolorspace element");
-      return;
-    }
-
-    if (!gst_bin_add (GST_BIN (self->priv->conference), ffmpegcolorspace))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not add the ffmpegcolorspace element to the FsMsnConference");
-      gst_object_unref (ffmpegcolorspace);
-      return;
-    }
-
-    if (!gst_element_sync_state_with_parent  (ffmpegcolorspace))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION,
-          "Could not sync state with parent for ffmpegcolorspace element");
-      return;
-    }
-
-    tmp_src_pad = gst_element_get_static_pad (ffmpegcolorspace, "src");
-    self->priv->src_pad = gst_ghost_pad_new ("src", tmp_src_pad);
-    gst_object_unref (tmp_src_pad);
-
-    gst_pad_set_active(self->priv->src_pad, TRUE);
-
-    if (!gst_element_add_pad (GST_ELEMENT (self->priv->conference),
-            self->priv->src_pad))
-    {
-      self->priv->construction_error = g_error_new (FS_ERROR,
-          FS_ERROR_CONSTRUCTION, "Could not add sink pad to conference");
-      gst_object_unref (self->priv->src_pad);
-      self->priv->src_pad = NULL;
-      return;
-    }
-
-    gst_element_link_many(self->priv->media_fd_src, mimdec, queue,
-        ffmpegcolorspace, NULL);
-
   }
   else
   {
@@ -574,7 +361,6 @@ _new_local_candidate (
               NULL)));
 }
 
-
 static void
 _connected (
     FsMsnConnection *connection,
@@ -582,45 +368,146 @@ _connected (
     gpointer user_data)
 {
   FsMsnStream *self = FS_MSN_STREAM (user_data);
+  GError *error = NULL;
+  GstPad *pad;
+  GstElement *fdelem;
   int checkfd;
 
   GST_DEBUG ("******** CONNECTED %d**********", fd);
-  if (self->priv->media_fd_src) {
-    FsCodec *mimic_codec = fs_codec_new (FS_CODEC_ID_ANY, "mimic",
+
+  if (self->priv->orig_direction == FS_DIRECTION_RECV)
+    self->priv->codecbin = gst_parse_bin_from_description (
+        "fdsrc name=fdsrc ! mimdec", TRUE, &error);
+  else
+    self->priv->codecbin = gst_parse_bin_from_description (
+        "ffmpegcolorspace ! videoscale ! mimenc ! fdsink name=fdsink",
+        TRUE, &error);
+
+  if (!self->priv->codecbin)
+  {
+    fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION,
+        "Could not build codecbin", error->message);
+    g_clear_error (&error);
+    return;
+  }
+
+
+  if (self->priv->orig_direction == FS_DIRECTION_RECV)
+    fdelem = gst_bin_get_by_name (GST_BIN (self->priv->codecbin), "fdsrc");
+  else
+    fdelem = gst_bin_get_by_name (GST_BIN (self->priv->codecbin), "fdsink");
+
+  if (!fdelem)
+  {
+    fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION,
+        "Could not get fd element",
+        "Could not get fd element");
+      gst_object_unref (self->priv->codecbin);
+      self->priv->codecbin = NULL;
+      return;
+  }
+
+  g_object_set (fdelem, "fd", fd, NULL);
+  g_object_get (fdelem, "fd", &checkfd, NULL);
+  gst_object_unref (fdelem);
+
+  if (fd != checkfd)
+  {
+    fs_stream_emit_error (FS_STREAM (self), FS_ERROR_INTERNAL,
+        "Could not set file descriptor", "Could not set fd");
+    gst_object_unref (self->priv->codecbin);
+    self->priv->codecbin = NULL;
+    return;
+  }
+
+  if (self->priv->orig_direction == FS_DIRECTION_RECV)
+    pad = gst_element_get_static_pad (self->priv->codecbin, "src");
+  else
+    pad = gst_element_get_static_pad (self->priv->codecbin, "sink");
+
+  if (!pad)
+  {
+    fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION,
+        "Could not get codecbin pad",
+        "Could not get codecbin pad");
+    gst_object_unref (self->priv->codecbin);
+    self->priv->codecbin = NULL;
+    return;
+  }
+
+  if (!gst_bin_add (GST_BIN (self->priv->conference), self->priv->codecbin))
+  {
+    fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION,
+        "Could not add codecbin to the conference",
+        "Could not add codecbin to the conference");
+    gst_object_unref (pad);
+    gst_object_unref (self->priv->codecbin);
+    self->priv->codecbin = NULL;
+    return;
+  }
+
+  if (self->priv->orig_direction == FS_DIRECTION_RECV)
+  {
+    FsCodec *mimic_codec;
+
+    self->priv->src_pad = gst_ghost_pad_new ("src_1_1_1", pad);
+    gst_object_unref (pad);
+
+    if (!gst_element_add_pad (GST_ELEMENT (self->priv->conference),
+            self->priv->src_pad))
+    {
+         fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION,
+             "Could not add src_1_1_1 pad",
+             "Could not add src_1_1_1 pad");
+         gst_object_unref (self->priv->src_pad);
+         self->priv->src_pad = NULL;
+      return;
+    }
+
+    mimic_codec = fs_codec_new (0, "mimic",
         FS_MEDIA_TYPE_VIDEO, 0);
     fs_stream_emit_src_pad_added (FS_STREAM (self), self->priv->src_pad,
         mimic_codec);
     fs_codec_destroy (mimic_codec);
+  }
+  else
+  {
+    GstPad *valvepad = gst_element_get_static_pad (self->priv->session_valve,
+        "src");
 
-    g_object_set (self->priv->media_fd_src, "fd", fd, NULL);
-    g_object_get (self->priv->media_fd_src, "fd", &checkfd, NULL);
-    if (fd != checkfd)
+    if (!valvepad)
     {
-      GST_ERROR ("Failed to set fd");
+      gst_object_unref (pad);
+      fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION,
+          "Could not get valve sink pad",
+          "Could not get valve sink pad");
       return;
     }
-    gst_element_set_locked_state(self->priv->media_fd_src, FALSE);
-    gst_element_sync_state_with_parent (self->priv->media_fd_src);
-  }
-  else if (self->priv->media_fd_sink)
-  {
-    g_object_set (G_OBJECT (self->priv->media_fd_sink), "fd", fd, NULL);
-    g_object_get (self->priv->media_fd_src, "fd", &checkfd, NULL);
-    if (fd != checkfd)
+
+    if (GST_PAD_LINK_FAILED (gst_pad_link (valvepad, pad)))
     {
-      GST_ERROR ("Failed to set fd");
+      gst_object_unref (valvepad);
+      gst_object_unref (pad);
+      fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION,
+          "Could not link valve to codec bin",
+          "Could not link valve to codec bin");
       return;
     }
-    gst_element_set_locked_state(self->priv->media_fd_src, FALSE);
-
-    gst_element_set_locked_state(self->priv->media_fd_sink,FALSE);
-    gst_element_sync_state_with_parent (self->priv->media_fd_sink);
-    g_object_set (G_OBJECT (self->priv->session_valve), "drop", FALSE, NULL);
+    gst_object_unref (valvepad);
+    gst_object_unref (pad);
   }
-  else
+
+  if (!gst_element_sync_state_with_parent (self->priv->codecbin))
   {
-    GST_ERROR ("no media fd src/sink...");
+    fs_stream_emit_error (FS_STREAM (self), FS_ERROR_CONSTRUCTION,
+        "Could not start codec bin",
+        "Could not start codec bin");
+    return;
   }
+
+
+  if (self->priv->direction == FS_DIRECTION_SEND)
+    g_object_set (G_OBJECT (self->priv->session_valve), "drop", FALSE, NULL);
 }
 
 /**
@@ -678,11 +565,6 @@ fs_msn_stream_new (FsMsnSession *session,
     return NULL;
   }
 
-  if (self->priv->sink_pad)
-  {
-    gst_pad_link (gst_element_get_static_pad (session_valve, "src"),
-        self->priv->sink_pad);
-  }
   self->priv->session_valve = session_valve;
 
   self->priv->connection = fs_msn_connection_new (session_id, initial_port);
-- 
1.5.6.5




More information about the farsight-commits mailing list