Logo Search packages:      
Sourcecode: farsight version File versions

farsight-transmitter.c

/*
 * farsight-transmitter.c - Base class for network transmitter plugins
 *
 * Farsight Core
 * Copyright (C) 2006 Collabora Ltd.
 * Copyright (C) 2006 Nokia Corporation
 *   @author Philippe Kalaf <philippe.kalaf@collabora.co.uk>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/**
 * SECTION:farsight-transmitter
 * @short_description: A object that represents a network transmitter
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "farsight-marshal.h"
#include "farsight-transmitter.h"

/* properties */
enum
{
  PROP_0,
  PROP_MEDIA_TYPE
};

/* Signals */
enum
{
  ERROR,
  NEW_NATIVE_CANDIDATE,
  NATIVE_CANDIDATES_PREPARED,
  NEW_ACTIVE_CANDIDATE_PAIR,
  CONNECTION_STATE_CHANGED,
  LAST_SIGNAL
};

struct _FarsightTransmitterPrivate
{
  gboolean disposed;
  FarsightMediaType media_type;
};

#define FARSIGHT_TRANSMITTER_GET_PRIVATE(o)  \
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), FARSIGHT_TYPE_TRANSMITTER, FarsightTransmitterPrivate))

static void farsight_transmitter_class_init (FarsightTransmitterClass *klass);
static void farsight_transmitter_init (FarsightTransmitter *self);
static void farsight_transmitter_dispose (GObject *object);
static void farsight_transmitter_finalize (GObject *object);

static void farsight_transmitter_get_property (GObject *object, 
                                          guint prop_id, 
                                          GValue *value,
                                          GParamSpec *pspec);
static void farsight_transmitter_set_property (GObject *object, 
                                          guint prop_id,
                                          const GValue *value, 
                                          GParamSpec *pspec);

static GObjectClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };

GType
farsight_transmitter_get_type (void)
{
  static GType type = 0;

  if (type == 0) {
    static const GTypeInfo info = {
      sizeof (FarsightTransmitterClass),
      NULL,
      NULL,
      (GClassInitFunc) farsight_transmitter_class_init,
      NULL,
      NULL,
      sizeof (FarsightTransmitter),
      0,
      (GInstanceInitFunc) farsight_transmitter_init
    };

    type = g_type_register_static (G_TYPE_OBJECT,
        "FarsightTransmitter", &info, 0);
  }

  return type;
}

static void
farsight_transmitter_class_init (FarsightTransmitterClass *klass)
{
  GObjectClass *gobject_class;

  gobject_class = (GObjectClass *) klass;
  parent_class = g_type_class_peek_parent (klass);

  gobject_class->set_property = farsight_transmitter_set_property;
  gobject_class->get_property = farsight_transmitter_get_property;

  g_object_class_install_property (gobject_class, PROP_MEDIA_TYPE,
      g_param_spec_uint ("media_type", "Stream media type",
        "The media type (audio/video) of the stream",
        FARSIGHT_MEDIA_TYPE_AUDIO,
        FARSIGHT_MEDIA_TYPE_LAST,
        FARSIGHT_MEDIA_TYPE_AUDIO,
        G_PARAM_READWRITE));

  /**
   * FarsightTransmitter::error:
   * @self: #FarsightTransmitter that emitted the signal
   * @type: #FarsightTransmitterError type of error
   * @message: Error message
   *
   * This signal is emitted in any error condition
   */
  signals[ERROR] = g_signal_new ("error",
      G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST,
      0,
      NULL,
      NULL,
      farsight_marshal_VOID__INT_STRING,
      G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);

  /**
   * FarsightTransmitter::new-native-candidate:
   * @self: #FarsightTransmitter that emitted the signal
   * @candidate: a #FarsightTransportInfo of the new native candidate
   *
   * This signal is emitted when a new native candidate is found.
   */
  signals[NEW_NATIVE_CANDIDATE] = g_signal_new ("new-native-candidate",
      G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST,
      0,
      NULL,
      NULL,
      g_cclosure_marshal_VOID__POINTER,
      G_TYPE_NONE, 1, G_TYPE_POINTER);

  /**
   * FarsightTransmitter::native-candidates-prepared:
   * @self: #FarsightTransmitter that emitted the signal
   *
   * This signal is emitted when the native candidates have been prepared.  This
   * usually means all of the local ports have been opened, local interfaces have
   * been found, and/or external ports have been found, and/or relay server has
   * been setup, or anything else the protocol needs.  After emission of this
   * signal, #farsight_transmitter_get_native_candidate_list should return
   * meaningful data
   */
  signals[NATIVE_CANDIDATES_PREPARED] = g_signal_new ("native-candidates-prepared",
      G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST,
      0,
      NULL,
      NULL,
      g_cclosure_marshal_VOID__VOID,
      G_TYPE_NONE, 0);

  /**
   * FarsightTransmitter::new-active-candidate-pair:
   * @self: #FarsightTransmitter that emitted the signal
   * @native_candidate_id: string identifier of native candidate that is now active
   * @remote_candidate_id: string identifier of remote candidate that is now active
   *
   * Emitted when this FarsightTransmitter has chosen a new active candidate pair
   * to use to connect to the remote client. 
   */
  signals[NEW_ACTIVE_CANDIDATE_PAIR] = 
    g_signal_new ("new-active-candidate-pair",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  0,
                  NULL,
                  NULL,
                  farsight_marshal_VOID__STRING_STRING,
                  G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);

  /**
   * FarsightTransmitter::connection-state-changed:
   * @self: #FarsightTransmitter that emitted the signal
   * @state: #FarsightTransmitterState of new state
   *
   * This signal is emitted when the connection state changes.
   */
  signals[CONNECTION_STATE_CHANGED] = g_signal_new ("connection-state-changed",
      G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST,
      0,
      NULL,
      NULL,
      farsight_marshal_VOID__INT,
      G_TYPE_NONE, 1, G_TYPE_INT);

  gobject_class->dispose = farsight_transmitter_dispose;
  gobject_class->finalize = farsight_transmitter_finalize;

  g_type_class_add_private (klass, sizeof (FarsightTransmitterPrivate));
}

static void
farsight_transmitter_init (FarsightTransmitter *self)
{
  /* member init */
  self->priv = FARSIGHT_TRANSMITTER_GET_PRIVATE (self);
  self->priv->disposed = FALSE;
}

static void
farsight_transmitter_dispose (GObject *object)
{
  FarsightTransmitter *self = FARSIGHT_TRANSMITTER (object);

  if (self->priv->disposed)
  {
    /* If dispose did already run, return. */
    return;
  }

  /* Make sure dispose does not run twice. */
  self->priv->disposed = TRUE;

  parent_class->dispose (object);
}

static void
farsight_transmitter_finalize (GObject *object)
{
  parent_class->finalize (object);
}

/**
 * farsight_transmitter_destroy:
 * @self: a #FarsightTransmitter
 *
 * Destroy this transmitter and all resources allocated by it. 
 * This function should be used instead of g_object_unref in order
 * to destroy the transmitter.
 **/
void
farsight_transmitter_destroy (FarsightTransmitter *self)
{
  g_object_unref (self);
}


FarsightTransmitter *
farsight_transmitter_factory_make (const gchar *transmitter_id)
{
  FarsightTransmitter *transmitter;
  FarsightPlugin *plugin;

  g_return_val_if_fail (transmitter_id != NULL, NULL);

  transmitter = FARSIGHT_TRANSMITTER(farsight_plugin_create(transmitter_id, 
                                         "transmitter", &plugin));
  if (transmitter == NULL) {
    g_print ("Failed to load plugin\n");
    return NULL;
  }

  transmitter->plugin = plugin;

  return transmitter;
}

/**
 * farsight_transmitter_prepare:
 * @self: a #FarsightTransmitter
 *
 * This tells the transmitter to prepare itself for transmission. Basically it
 * discovers local candidates, opens sockets and other specific operations.
 *
 * Returns: FALSE if the preparation failed.
 *
 **/
gboolean
farsight_transmitter_prepare (FarsightTransmitter *self)
{
  FarsightTransmitterClass *klass = FARSIGHT_TRANSMITTER_GET_CLASS (self);
  g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (self),
              FARSIGHT_TYPE_TRANSMITTER), FALSE);

  if (klass->prepare)
  {
    return klass->prepare (self);
  }
  else
  {
    g_warning ("prepare not defined for %s",
        G_OBJECT_TYPE_NAME (self));
  }
  return FALSE;
}

/**
 * farsight_transmitter_stop:
 * @self: a #FarsightTransmitter
 *
 * This tells the transmitter to stop transmitting and shutdown any sockets.
 *
 * Returns: FALSE if the shutdown sequence fails.
 *
 **/
gboolean
farsight_transmitter_stop (FarsightTransmitter *self)
{
  FarsightTransmitterClass *klass = FARSIGHT_TRANSMITTER_GET_CLASS (self);
  g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (self),
              FARSIGHT_TYPE_TRANSMITTER), FALSE);

  if (klass->stop)
  {
    return klass->stop (self);
  }
  else
  {
    g_warning ("stop not defined for %s",
        G_OBJECT_TYPE_NAME (self));
  }
  return FALSE;
}

/**
 * farsight_transmitter_add_remote_candidates:
 * @self: a #FarsightTransmitter
 * @remote_candidate_list: a #GList of #FarsightTransport of the remote
 * candidates
 *
 * Tells the transmitter what the remote candidates are for transmission.
 *
 **/
void
farsight_transmitter_add_remote_candidates (FarsightTransmitter *self,
    const GList *remote_candidate_list)
{
  FarsightTransmitterClass *klass = FARSIGHT_TRANSMITTER_GET_CLASS (self);
  g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (self),
        FARSIGHT_TYPE_TRANSMITTER));
  g_return_if_fail (remote_candidate_list != NULL);

  if (klass->add_remote_candidates)
  {
    klass->add_remote_candidates (self, remote_candidate_list);
  }
  else
  {
    g_warning ("add_remote_candidates not defined for %s",
        G_OBJECT_TYPE_NAME (self));
  }
}

/**
 * farsight_transmitter_get_gst_src:
 * @self: a #FarsightTransmitter
 *
 * Asks the transmitter to return the pointer to the gstreamer source used by
 * this transmitter.
 *
 * Returns: a pointer a source #GstElement to use.
 *
 **/
GstElement *
farsight_transmitter_get_gst_src (FarsightTransmitter *self)
{
  FarsightTransmitterClass *klass = FARSIGHT_TRANSMITTER_GET_CLASS (self);
  g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (self),
        FARSIGHT_TYPE_TRANSMITTER), NULL);

  if (klass->get_gst_src)
  {
    return klass->get_gst_src (self);
  }
  else
  {
    g_warning ("get_gst_src not defined for %s",
        G_OBJECT_TYPE_NAME (self));
  }
  return NULL;
}

/**
 * farsight_transmitter_get_gst_sink:
 * @self: a #FarsightTransmitter
 *
 * Asks the transmitter to return the pointer to the gstreamer sink used by
 * this transmitter.
 *
 * Returns: a pointer a sink #GstElement to use.
 *
 **/
GstElement *
farsight_transmitter_get_gst_sink (FarsightTransmitter *self)
{
  FarsightTransmitterClass *klass = FARSIGHT_TRANSMITTER_GET_CLASS (self);
  g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (self),
        FARSIGHT_TYPE_TRANSMITTER), NULL);

  if (klass->get_gst_sink)
  {
    return klass->get_gst_sink (self);
  }
  else
  {
    g_warning ("get_gst_sink not defined for %s",
        G_OBJECT_TYPE_NAME (self));
  }
  return NULL;
}

/**
 * farsight_tranasmitter_signal_new_native_candidate:
 * @self: a #FarsightTransmitter
 * @trans: a #FarsightTransportInfo of the new native candidate
 *
 * Used by subclasses of #FarsightTransmitter to emit an
 * <link linkend="FarsightTransmitter-new-native-candidate">
 * new-native-candidate </link> signal
 */
void farsight_transmitter_signal_new_native_candidate (
    FarsightTransmitter *self,
    const FarsightTransportInfo *candidate)
{
  g_signal_emit (self, signals[NEW_NATIVE_CANDIDATE], 0, candidate);
}

/**
 * farsight_transmitter_signal_new_active_candidates_prepared:
 * @self: a #FarsightTransmitter
 *
 * Used by subclasses of #FarsightTransmitter to emit an
 * <link linkend="FarsightTransmitter-native_candidates_prepared">
 * native-candidates-prepared </link> signal
 */
void farsight_transmitter_signal_native_candidates_prepared (
    FarsightTransmitter *self)
{
  g_signal_emit (self, signals[NATIVE_CANDIDATES_PREPARED], 0);
}

/**
 * farsight_transmitter_signal_new_active_candidate_pair:
 * @self: a #FarsightTransmitter
 * @native_candidate_id: string identifier of native candidate that is now active
 * @remote_candidate_id: string identifier of remote candidate that is now active
 *
 * Used by subclasses of #FarsightTransmitter to emit an
 * <link linkend="FarsightTransmitter-new-active-candidate-pair">
 * new-active-candidate-pair </link> signal
 */
void farsight_transmitter_signal_new_active_candidate_pair (
    FarsightTransmitter *self,
    const gchar *native_candidate_id,
    const gchar *remote_candidate_id)
{
  g_signal_emit (self, signals[NEW_ACTIVE_CANDIDATE_PAIR], 0,
      native_candidate_id, remote_candidate_id);
}

/**
 * farsight_transmitter_signal_error:
 * @self: #FarsightTransmitter that emitted the signal
 * @type: #FarsightTransmitterError type of error
 * @message: Error message
 *
 * Used by subclasses of #FarsightTransmitter to emit an
 * <link linkend="FarsightTransmitter-error">
 * error </link> signal
 */
void farsight_transmitter_signal_error (
    FarsightTransmitter *self,
    FarsightTransmitterError type,
    gchar *message)
{
  g_signal_emit (self, signals[ERROR], 0,
      type, message);
}

/**
 * farsight_transmitter_signal_connection_state_changed:
 * @self: #FarsightTransmitter that emitted the signal
 * @state: #FarsighmTransmitterState of new state
 *
 * Used by subclasses of #FarsightTransmitter to emit an
 * <link linkend="FarsightTransmitter-connection-state-changed">
 * connection-state-changed </link> signal
 */
void farsight_transmitter_signal_connection_state_changed (
    FarsightTransmitter *self,
    FarsightTransmitterState state)
{
  g_signal_emit (self, signals[CONNECTION_STATE_CHANGED], 0, state);
}

static void
farsight_transmitter_set_property (GObject *object,
                                   guint prop_id,
                                   const GValue *value,
                                   GParamSpec *pspec)
{
  FarsightTransmitter *self;

  g_return_if_fail (FARSIGHT_IS_TRANSMITTER (object));

  self = FARSIGHT_TRANSMITTER (object);

  switch (prop_id) {
    case PROP_MEDIA_TYPE:
      self->priv->media_type = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
farsight_transmitter_get_property (GObject *object,
                                   guint prop_id,
                                   GValue *value,
                                   GParamSpec *pspec)
{
  FarsightTransmitter *self;

  g_return_if_fail (FARSIGHT_IS_TRANSMITTER (object));

  self = FARSIGHT_TRANSMITTER (object);

  switch (prop_id) {
    case PROP_MEDIA_TYPE:
      g_value_set_uint (value, self->priv->media_type);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

Generated by  Doxygen 1.6.0   Back to index