/** * fs_msn_session_new_stream: * @session: an #FsMsnSession * @participant: #FsParticipant of a participant for the new stream * @direction: #FsStreamDirection describing the direction of the new stream that will * be created for this participant * @error: location of a #GError, or NULL if no error occured * * This function creates a stream for the given participant into the active session. * * Returns: the new #FsStream that has been created. User must unref the * #FsStream when the stream is ended. If an error occured, returns NULL. */ static FsStream * fs_msn_session_new_stream (FsSession *session, FsParticipant *participant, FsStreamDirection direction, const gchar *transmitter, guint n_parameters, GParameter *parameters, GError **error) { FsMsnSession *self = FS_MSN_SESSION (session); FsMsnParticipant *msnparticipant = NULL; FsStream *new_stream = NULL; if (!FS_IS_MSN_PARTICIPANT (participant)) { g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS, "You have to provide a participant of type MSN"); return NULL; } msnparticipant = FS_MSN_PARTICIPANT (participant); new_stream = FS_STREAM_CAST (fs_msn_stream_new (self, msnparticipant, direction,self->priv->conference,error)); FS_MSN_SESSION_LOCK (self); self->priv->streams = g_list_append (self->priv->streams, new_stream); FS_MSN_SESSION_UNLOCK (self); g_object_weak_ref (G_OBJECT (new_stream), _remove_stream, self); return new_stream; }
static void fs_msn_session_finalize (GObject *object) { FsMsnSession *self = FS_MSN_SESSION (object); g_static_rec_mutex_free (&self->mutex); parent_class->finalize (object); }
static void _remove_stream (gpointer user_data, GObject *where_the_object_was) { FsMsnSession *self = FS_MSN_SESSION (user_data); FS_MSN_SESSION_LOCK (self); self->priv->streams = g_list_remove_all (self->priv->streams, where_the_object_was); FS_MSN_SESSION_UNLOCK (self); }
static void fs_msn_session_dispose (GObject *object) { FsMsnSession *self = FS_MSN_SESSION (object); GstBin *conferencebin = NULL; if (self->priv->disposed) /* If dispose did already run, return. */ return; conferencebin = GST_BIN (self->priv->conference); FS_MSN_SESSION_UNLOCK (self); /* MAKE sure dispose does not run twice. */ self->priv->disposed = TRUE; parent_class->dispose (object); }
static void fs_msn_session_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { FsMsnSession *self = FS_MSN_SESSION (object); switch (prop_id) { case PROP_MEDIA_TYPE: self->priv->media_type = g_value_get_enum (value); break; case PROP_ID: self->id = g_value_get_uint (value); break; case PROP_CONFERENCE: self->priv->conference = FS_MSN_CONFERENCE (g_value_dup_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void fs_msn_stream_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { FsMsnStream *self = FS_MSN_STREAM (object); FsMsnConference *conference = fs_msn_stream_get_conference (self, NULL); if (!conference && !(pspec->flags & (G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT))) return; if (conference) GST_OBJECT_LOCK (conference); switch (prop_id) { case PROP_SESSION: self->priv->session = FS_MSN_SESSION (g_value_dup_object (value)); break; case PROP_PARTICIPANT: self->priv->participant = FS_MSN_PARTICIPANT (g_value_dup_object (value)); break; case PROP_DIRECTION: if (g_value_get_flags (value) != self->priv->direction) { GstElement *recv_valve = NULL; GstElement *session_valve = NULL; if (!conference || !self->priv->recv_valve || !self->priv->session) { self->priv->direction = g_value_get_flags (value); break; } if (self->priv->recv_valve) recv_valve = gst_object_ref (self->priv->recv_valve); if (self->priv->session->valve) session_valve = gst_object_ref (self->priv->session->valve); self->priv->direction = g_value_get_flags (value) & conference->max_direction; if (self->priv->direction == FS_DIRECTION_NONE) { GST_OBJECT_UNLOCK (conference); if (recv_valve) g_object_set (recv_valve, "drop", TRUE, NULL); g_object_set (session_valve, "drop", TRUE, NULL); GST_OBJECT_LOCK (conference); } else if (self->priv->direction == FS_DIRECTION_SEND) { if (self->priv->codecbin) { GST_OBJECT_UNLOCK (conference); g_object_set (session_valve, "drop", FALSE, NULL); GST_OBJECT_LOCK (conference); } } else if (self->priv->direction == FS_DIRECTION_RECV) { GST_OBJECT_UNLOCK (conference); if (recv_valve) g_object_set (recv_valve, "drop", FALSE, NULL); GST_OBJECT_LOCK (conference); } if (session_valve) gst_object_unref (session_valve); if (recv_valve) gst_object_unref (recv_valve); } self->priv->direction = g_value_get_flags (value); break; case PROP_CONFERENCE: self->priv->conference = FS_MSN_CONFERENCE (g_value_dup_object (value)); break; case PROP_SESSION_ID: self->priv->session_id = g_value_get_uint (value); if (self->priv->session_id == 0) self->priv->session_id = g_random_int_range (9000, 9999); break; case PROP_INITIAL_PORT: self->priv->initial_port = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } if (conference) { GST_OBJECT_UNLOCK (conference); gst_object_unref (conference); } }