コード例 #1
0
static void
mex_telepathy_channel_new_tf_channel (GObject      *source,
                                      GAsyncResult *result,
                                      gpointer      user_data)
{
  MexTelepathyChannel *self = MEX_TELEPATHY_CHANNEL (user_data);
  MexTelepathyChannelPrivate *priv = self->priv;

  MEX_DEBUG ("New TfChannel");

  priv->tf_channel = TF_CHANNEL (g_async_initable_new_finish (
                                   G_ASYNC_INITABLE (source), result, NULL));

  if (priv->tf_channel == NULL)
    {
      MEX_WARNING ("Failed to create channel");
      return;
    }

  MEX_DEBUG ("Adding timeout");
  priv->pipeline_timer = g_timeout_add_seconds (5,
                         mex_telepathy_channel_dump_pipeline,
                         self);

  g_signal_connect (priv->tf_channel, "fs-conference-added",
                    G_CALLBACK (mex_telepathy_channel_conference_added), self);

  g_signal_connect (priv->tf_channel, "content-added",
                    G_CALLBACK (mex_telepathy_channel_on_content_added), self);
}
コード例 #2
0
static gboolean
parse_line (MexUriChannelProvider *provider,
            const gchar           *line)
{
  MexUriChannelProviderPrivate *priv = provider->priv;
  gchar **fields, *name, *uri;
  MexChannel *channel;

  fields = g_strsplit (line, "|", 0);
  if (!(fields[0] && fields[1]))
    {
      MEX_WARNING ("Invalid channel definition in %s: %s",
                   priv->config_file, line);
      g_strfreev (fields);
      return FALSE;
    }

  name = fields[0];
  uri = fields[1];

  channel = g_object_new (MEX_TYPE_CHANNEL,
                          "name", name,
                          "uri", uri,
                          NULL);
  g_ptr_array_add (priv->channels, channel);
  g_strfreev (fields);

  return TRUE;
}
コード例 #3
0
static gboolean
parse_config (MexUriChannelProvider *provider)
{
  MexUriChannelProviderPrivate *priv = provider->priv;
  GFileInputStream *input;
  GDataInputStream *data;
  gboolean result = TRUE;
  GError *error = NULL;
  gchar *line;
  GFile *file;

  if (priv->channels)
    g_ptr_array_free (priv->channels, TRUE);
  priv->channels = g_ptr_array_new_with_free_func (g_object_unref);

  file = g_file_new_for_path (priv->config_file);
  input = g_file_read (file, NULL, &error);
  if (G_UNLIKELY (error))
    {
      MEX_WARNING ("Could not read config file %s: %s",
                   priv->config_file, error->message);
      g_clear_error (&error);
      goto read_error;
    }

  data = g_data_input_stream_new (G_INPUT_STREAM (input));

  line = g_data_input_stream_read_line (data, NULL, NULL, &error);
  while (line)
    {
      parse_line (provider, line);
      g_free (line);
      line = g_data_input_stream_read_line (data, NULL, NULL, &error);
    }
  if (G_UNLIKELY (error))
    {
      MEX_WARNING ("Could not read line: %s", error->message);
      g_clear_error (&error);
    }

  g_object_unref (data);
  g_object_unref (input);
read_error:
  g_object_unref (file);
  return result;
}
コード例 #4
0
void CommandDelete(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{ // delete class instance

  // Expected Input:
  //  cmd
  //  class handle

  // Warn if other commands were ignored
  if (nlhs != 0 || nrhs != 2)
  {
    MEX_WARNING("Delete: requires 0 outputs, 2 inputs.");
  }

  // Destroy the C++ object
  destroyObject<mexInterface_AlgPDTree_MLP_Mesh>(prhs[1]);
}
コード例 #5
0
static void
mex_telepathy_channel_on_content_added (TfChannel *channel,
                                        TfContent *content,
                                        gpointer   user_data)
{
  MexTelepathyChannel *self = MEX_TELEPATHY_CHANNEL (user_data);
  MexTelepathyChannelPrivate *priv = self->priv;
  GstPad *srcpad, *sinkpad;
  FsMediaType mtype;
  GstElement *element;
  GstStateChangeReturn ret;

  MEX_DEBUG ("Content added");

  g_object_get (content,
                "sink-pad", &sinkpad,
                "media-type", &mtype,
                NULL);

  switch (mtype)
    {
    case FS_MEDIA_TYPE_AUDIO:
      MEX_DEBUG ("Audio content added");
      element = gst_parse_bin_from_description (
        "autoaudiosrc ! audioresample ! audioconvert ! volume name=micvolume", TRUE, NULL);
      priv->outgoing_mic = element;
      priv->mic_volume = gst_bin_get_by_name (GST_BIN (priv->outgoing_mic), "micvolume");
      break;
    case FS_MEDIA_TYPE_VIDEO:
      MEX_DEBUG ("Video content added");
      element = mex_telepathy_channel_setup_video_source (self, content);
      break;
    default:
      MEX_WARNING ("Unknown media type");
      g_object_unref (sinkpad);
      return;
    }

  g_signal_connect (content, "src-pad-added",
                    G_CALLBACK (mex_telepathy_channel_on_src_pad_added), self);

  gst_bin_add (GST_BIN (priv->pipeline), element);
  srcpad = gst_element_get_pad (element, "src");

  if (GST_PAD_LINK_FAILED (gst_pad_link (srcpad, sinkpad)))
    {
      tp_channel_close_async (TP_CHANNEL (priv->channel), NULL, NULL);
      MEX_WARNING ("Couldn't link source pipeline !?");
      return;
    }

  ret = gst_element_set_state (element, GST_STATE_PLAYING);
  if (ret == GST_STATE_CHANGE_FAILURE)
    {
      tp_channel_close_async (TP_CHANNEL (priv->channel), NULL, NULL);
      MEX_WARNING ("source pipeline failed to start!?");
      return;
    }

  g_object_unref (srcpad);
  g_object_unref (sinkpad);
}
コード例 #6
0
static GstElement *
mex_telepathy_channel_setup_video_source (MexTelepathyChannel *self,
                                          TfContent           *content)
{
  MexTelepathyChannelPrivate *priv = self->priv;
  GstElement *result, *input, *rate, *scaler, *colorspace, *capsfilter, *tee;
  GstCaps *caps;
  guint framerate = 0, width = 0, height = 0;
  GstPad *pad, *ghost, *teesink, *teesrc, *outsink;

  result = gst_bin_new ("video_input");
  input = gst_element_factory_make ("autovideosrc", NULL);
  rate = gst_element_factory_make ("videomaxrate", NULL);
  scaler = gst_element_factory_make ("videoscale", NULL);
  colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
  capsfilter = gst_element_factory_make ("capsfilter", NULL);

  g_assert (input && rate && scaler && colorspace && capsfilter);
  g_object_get (content,
                "framerate", &framerate,
                "width", &width,
                "height", &height,
                NULL);

  if (framerate == 0)
    framerate = 15;

  if (width == 0 || height == 0)
    {
      width = 320;
      height = 240;
    }

  priv->framerate = framerate;
  priv->width = width;
  priv->height = height;

  caps = gst_caps_new_simple ("video/x-raw-yuv",
                              "width", G_TYPE_INT, width,
                              "height", G_TYPE_INT, height,
                              "framerate", GST_TYPE_FRACTION, framerate, 1,
                              NULL);

  g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL);

  gst_bin_add_many (GST_BIN (result), input, rate, scaler,
                    colorspace, capsfilter, NULL);
  g_assert (gst_element_link_many (input, rate, scaler,
                                   colorspace, capsfilter, NULL));

  pad = gst_element_get_static_pad (capsfilter, "src");
  g_assert (pad != NULL);

  tee = gst_element_factory_make("tee", NULL);
  if (!tee)
    {
      MEX_WARNING("Couldn't create tee element !?");
      return NULL;
    }

  teesink = gst_element_get_pad(tee, "sink");
  gst_bin_add (GST_BIN (result), tee);

  if (GST_PAD_LINK_FAILED (gst_pad_link (pad, teesink)))
    {
      MEX_WARNING ("Couldn't link source pipeline to tee !?");
      return NULL;
    }
  pad = gst_element_get_request_pad (tee, "src%d");

  // Link the tee to the preview widget.
  teesrc = gst_element_get_request_pad(tee, "src%d");
  outsink = gst_element_get_pad (self->priv->outgoing_sink, "sink");
  gst_bin_add (GST_BIN(result), self->priv->outgoing_sink);
  gst_pad_link (teesrc, outsink);

  ghost = gst_ghost_pad_new ("src", pad);
  gst_element_add_pad (result, ghost);

  g_object_unref (pad);

  priv->video_input = result;
  priv->video_capsfilter = capsfilter;

  g_signal_connect (content, "notify::framerate",
                    G_CALLBACK (
                      mex_telepathy_channel_on_video_framerate_changed),
                    self);

  g_signal_connect (content, "resolution-changed",
                    G_CALLBACK (
                      mex_telepathy_channel_on_video_resolution_changed),
                    self);

  return result;
}
コード例 #7
0
static void
mex_telepathy_channel_on_src_pad_added (TfContent *content,
                                        TpHandle   handle,
                                        FsStream  *stream,
                                        GstPad    *pad,
                                        FsCodec   *codec,
                                        gpointer   user_data)
{
  MexTelepathyChannel *self = MEX_TELEPATHY_CHANNEL (user_data);
  MexTelepathyChannelPrivate *priv = self->priv;

  gchar *cstr = fs_codec_to_string (codec);
  FsMediaType mtype;
  GstPad *sinkpad;
  GstElement *element;
  GstStateChangeReturn ret;

  /* Upon pad added, clear the "in progress" box+padding */
  clutter_actor_hide (CLUTTER_ACTOR (priv->busy_box));
  clutter_actor_show (CLUTTER_ACTOR (priv->full_frame) );

  MEX_DEBUG ("New src pad: %s", cstr);
  g_object_get (content, "media-type", &mtype, NULL);

  switch (mtype)
    {
    case FS_MEDIA_TYPE_AUDIO:
      element = gst_parse_bin_from_description (
        "audioconvert ! audioresample ! audioconvert ! autoaudiosink",
        TRUE, NULL);
      break;
    case FS_MEDIA_TYPE_VIDEO:
      element = priv->incoming_sink;
      break;
    default:
      MEX_WARNING ("Unknown media type");
      return;
    }

  if (!gst_bin_add (GST_BIN (priv->pipeline), element))
    {
      MEX_WARNING ("Failed to add sink element to pipeline");
    }
  sinkpad = gst_element_get_pad (element, "sink");
  ret = gst_element_set_state (element, GST_STATE_PLAYING);
  if (ret == GST_STATE_CHANGE_FAILURE)
    {
      tp_channel_close_async (TP_CHANNEL (priv->channel), NULL, NULL);
      MEX_WARNING ("Failed to start tee sink pipeline !?");
      return;
    }

  if (GST_PAD_LINK_FAILED (gst_pad_link (pad, sinkpad)))
    {
      tp_channel_close_async (TP_CHANNEL (priv->channel), NULL, NULL);
      MEX_WARNING ("Couldn't link sink pipeline !?");
      return;
    }

  g_object_unref (sinkpad);

  /* Start in FULL mode */
  mex_telepathy_channel_set_tool_mode (self, TOOL_MODE_FULL, 100);
}
コード例 #8
0
static void
mex_telepathy_channel_initialize_channel (MexTelepathyChannel *self)
{
  MexTelepathyChannelPrivate *priv = self->priv;

  GstBus *bus;
  GstElement *pipeline;
  GstStateChangeReturn ret;
  gboolean ready;

  TpHandle contactHandle = tp_channel_get_handle (priv->channel, NULL);
  TpContactFeature features[] = { TP_CONTACT_FEATURE_ALIAS,
                                  TP_CONTACT_FEATURE_AVATAR_DATA,
                                  TP_CONTACT_FEATURE_AVATAR_TOKEN};

  MEX_INFO ("New channel");

  if (contactHandle)
    tp_connection_get_contacts_by_handle (
      priv->connection, 1, &contactHandle, 1,
      features,
      mex_telepathy_channel_on_contact_fetched,
      self, NULL, NULL);

  pipeline = gst_pipeline_new (NULL);

  ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);

  if (ret == GST_STATE_CHANGE_FAILURE)
    {
      tp_channel_close_async (TP_CHANNEL (priv->channel), NULL, NULL);
      g_object_unref (pipeline);
      MEX_WARNING ("Failed to start an empty pipeline !?");
      return;
    }

  priv->pipeline = pipeline;

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  priv->buswatch = gst_bus_add_watch (bus, mex_telepathy_channel_on_bus_watch,
                                      self);
  g_object_unref (bus);

  tf_channel_new_async (priv->channel, mex_telepathy_channel_new_tf_channel,
                        self);

  tpy_cli_channel_type_call_call_accept (TP_PROXY (priv->channel), -1,
                                         NULL, NULL, NULL, NULL);

  priv->channel = g_object_ref (priv->channel);
  g_signal_connect (priv->channel, "notify::ready",
                    G_CALLBACK (mex_telepathy_channel_on_ready),
                    self);
  g_signal_connect (priv->channel, "invalidated",
                    G_CALLBACK (mex_telepathy_channel_on_proxy_invalidated),
                    self);

  g_signal_connect (TPY_CALL_CHANNEL (priv->channel), "state-changed",
                    G_CALLBACK (mex_telepathy_channel_on_call_state_changed),
                    self);

  g_object_get (priv->channel, "ready", &ready, NULL);
  if (ready)
    mex_telepathy_channel_on_ready (TPY_CALL_CHANNEL (priv->channel), NULL, self);
}