[farsight2/master] Always modify the send pipeline from the streaming thread
Olivier Crête
olivier.crete at collabora.co.uk
Fri Dec 19 19:44:07 PST 2008
---
gst/fsrtpconference/fs-rtp-session.c | 271 +++++++++++++++++-----------------
1 files changed, 134 insertions(+), 137 deletions(-)
diff --git a/gst/fsrtpconference/fs-rtp-session.c b/gst/fsrtpconference/fs-rtp-session.c
index 721bbd0..ef64f2c 100644
--- a/gst/fsrtpconference/fs-rtp-session.c
+++ b/gst/fsrtpconference/fs-rtp-session.c
@@ -136,8 +136,6 @@ struct _FsRtpSessionPrivate
*/
GstPad *media_sink_pad;
- GList *extra_send_capsfilters;
-
/* The discovery elements are only created when codec parameter discovery is
* under progress.
* They are normally destroyed when the caps are found but may be destroyed
@@ -162,6 +160,7 @@ struct _FsRtpSessionPrivate
/* Can only be modified by the streaming thread with the pad blocked */
GstElement *send_codecbin;
+ GList *extra_send_capsfilters;
/* These lists are protected by the session mutex */
GList *streams;
@@ -228,10 +227,7 @@ static gboolean fs_rtp_session_set_send_codec (FsSession *session,
static gboolean fs_rtp_session_set_codec_preferences (FsSession *session,
GList *codec_preferences,
GError **error);
-static gboolean fs_rtp_session_verify_send_codec_bin_locked (
- FsRtpSession *self,
- GError **error);
-static void fs_rtp_session_send_codec_changed_unlock (FsRtpSession *self);
+static void fs_rtp_session_verify_send_codec_bin (FsRtpSession *self);
static gchar **fs_rtp_session_list_transmitters (FsSession *session);
@@ -1560,7 +1556,7 @@ fs_rtp_session_set_send_codec (FsSession *session, FsCodec *send_codec,
GError **error)
{
FsRtpSession *self = FS_RTP_SESSION (session);
- gboolean ret = FALSE;
+ gboolean ret = TRUE;
FS_RTP_SESSION_LOCK (self);
@@ -1572,7 +1568,8 @@ fs_rtp_session_set_send_codec (FsSession *session, FsCodec *send_codec,
self->priv->requested_send_codec = fs_codec_copy (send_codec);
- ret = fs_rtp_session_verify_send_codec_bin_locked (self, error);
+ fs_rtp_session_verify_send_codec_bin (self);
+ ret = TRUE;
}
else
{
@@ -2180,15 +2177,13 @@ fs_rtp_session_update_codecs (FsRtpSession *session,
fs_rtp_session_start_codec_param_gathering_locked (session);
+ FS_RTP_SESSION_UNLOCK (session);
+
if (has_remotes)
{
- if (!fs_rtp_session_verify_send_codec_bin_locked (session, error))
- return FALSE;
+ fs_rtp_session_verify_send_codec_bin (session);
}
- FS_RTP_SESSION_UNLOCK (session);
-
-
if (is_new)
{
g_object_notify (G_OBJECT (session), "codecs");
@@ -3077,6 +3072,92 @@ link_other_pads (gpointer item, GValue *ret, gpointer user_data)
return FALSE;
}
+
+static gboolean
+fs_rtp_session_remove_send_codec_bin (FsRtpSession *self,
+ FsCodec *codec_without_config,
+ gboolean error_emit)
+{
+ if (self->priv->send_codecbin)
+ {
+ gst_element_set_locked_state (self->priv->send_codecbin, TRUE);
+ if (gst_element_set_state (self->priv->send_codecbin, GST_STATE_NULL) !=
+ GST_STATE_CHANGE_SUCCESS)
+ {
+ gst_element_set_locked_state (self->priv->send_codecbin, FALSE);
+ if (error_emit)
+ fs_session_emit_error (FS_SESSION (self), FS_ERROR_INTERNAL,
+ "Could not stop the codec bin",
+ "Setting the codec bin to NULL did not succeed" );
+ return FALSE;
+ }
+
+ gst_bin_remove (GST_BIN (self->priv->conference),
+ self->priv->send_codecbin);
+ self->priv->send_codecbin = NULL;
+ }
+
+ FS_RTP_SESSION_LOCK (self);
+ fs_codec_destroy (self->priv->current_send_codec);
+ self->priv->current_send_codec = NULL;
+ FS_RTP_SESSION_UNLOCK (self);
+
+ while (self->priv->extra_send_capsfilters)
+ {
+ GstElement *cf = self->priv->extra_send_capsfilters->data;
+ GstPad *ourpad = gst_element_get_static_pad (cf, "src");
+ GstPad *pad = NULL;
+
+ if (ourpad)
+ {
+ pad = gst_pad_get_peer (ourpad);
+ if (pad)
+ {
+ gst_pad_set_active (pad, FALSE);
+ gst_element_release_request_pad (self->priv->rtpmuxer, pad);
+ gst_object_unref (pad);
+ }
+ gst_object_unref (ourpad);
+ }
+
+ gst_element_set_locked_state (cf, TRUE);
+ gst_element_set_state (cf, GST_STATE_NULL);
+ gst_bin_remove (GST_BIN (self->priv->conference), cf);
+
+ self->priv->extra_send_capsfilters = g_list_delete_link (
+ self->priv->extra_send_capsfilters,
+ self->priv->extra_send_capsfilters);
+ }
+
+ if (codec_without_config)
+ {
+ GError *error = NULL;
+
+ FS_RTP_SESSION_LOCK (self);
+ self->priv->extra_sources = fs_rtp_special_sources_remove (
+ self->priv->extra_sources,
+ self->priv->codec_associations, codec_without_config,
+ GST_ELEMENT (self->priv->conference),
+ self->priv->rtpmuxer);
+ FS_RTP_SESSION_UNLOCK (self);
+ if (error)
+ {
+ if (error_emit)
+ fs_session_emit_error (FS_SESSION (self), FS_ERROR_INTERNAL,
+ "Could not remove unused special sources",
+ "Could not remove unused special sources");
+ return FALSE;
+ }
+ }
+ /*
+ * Lets reset the clock-rate (because rtpmuxer saves it.. )
+ */
+ g_object_set (self->priv->rtpmuxer, "clock-rate", 0, NULL);
+
+ return TRUE;
+}
+
+
/**
* fs_rtp_session_add_send_codec_bin_unlock:
* @session: a #FsRtpSession
@@ -3114,13 +3195,16 @@ fs_rtp_session_add_send_codec_bin_unlock (FsRtpSession *session,
codecbin = _create_codec_bin (ca, codec, name, TRUE, codecs, error);
g_free (name);
+ FS_RTP_SESSION_UNLOCK (session);
+
if (!codecbin)
{
fs_codec_list_destroy (codecs);
- FS_RTP_SESSION_UNLOCK (session);
return NULL;
}
+ gst_element_set_locked_state (codecbin, TRUE);
+
if (!gst_bin_add (GST_BIN (session->priv->conference), codecbin))
{
g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
@@ -3128,7 +3212,6 @@ fs_rtp_session_add_send_codec_bin_unlock (FsRtpSession *session,
codec->id);
gst_object_unref (codecbin);
fs_codec_list_destroy (codecs);
- FS_RTP_SESSION_UNLOCK (session);
return NULL;
}
@@ -3139,7 +3222,6 @@ fs_rtp_session_add_send_codec_bin_unlock (FsRtpSession *session,
"Could not get the valve sink for the send codec bin");
gst_bin_remove (GST_BIN (session->priv->conference), (codecbin));
fs_codec_list_destroy (codecs);
- FS_RTP_SESSION_UNLOCK (session);
return NULL;
}
@@ -3192,6 +3274,7 @@ fs_rtp_session_add_send_codec_bin_unlock (FsRtpSession *session,
if (!g_value_get_boolean (&link_rv))
goto error;
+ gst_element_set_locked_state (codecbin, FALSE);
if (!gst_element_sync_state_with_parent (codecbin))
{
@@ -3204,53 +3287,33 @@ fs_rtp_session_add_send_codec_bin_unlock (FsRtpSession *session,
g_object_set (session->priv->media_sink_valve, "drop", FALSE, NULL);
session->priv->send_codecbin = codecbin;
+
+ FS_RTP_SESSION_LOCK (session);
session->priv->current_send_codec = fs_codec_copy (codec);
+ FS_RTP_SESSION_UNLOCK (session);
+
+ g_object_notify (G_OBJECT (session), "current-send-codec");
+
+ gst_element_post_message (GST_ELEMENT (session->priv->conference),
+ gst_message_new_element (GST_OBJECT (session->priv->conference),
+ gst_structure_new ("farsight-send-codec-changed",
+ "session", FS_TYPE_SESSION, session,
+ "codec", FS_TYPE_CODEC, codec,
+ NULL)));
- fs_rtp_session_send_codec_changed_unlock (session);
fs_codec_list_destroy (codecs);
return codecbin;
error:
- gst_element_set_locked_state (codecbin, TRUE);
- gst_element_set_state (codecbin, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (session->priv->conference), codecbin);
+ fs_rtp_session_remove_send_codec_bin (session, NULL, FALSE);
fs_codec_list_destroy (codecs);
FS_RTP_SESSION_UNLOCK (session);
return NULL;
}
-/**
- * fs_rtp_session_send_codec_changed_unlock:
- * @self: The #FsRtpSession that changed its codec
- *
- * Call this function when the value of the #FsSession:current-send-codec
- * changes
- */
-
-static void
-fs_rtp_session_send_codec_changed_unlock (FsRtpSession *self)
-{
- FsCodec *codec = NULL;
-
- codec = fs_codec_copy (self->priv->current_send_codec);
-
- FS_RTP_SESSION_UNLOCK (self);
-
- g_object_notify (G_OBJECT (self), "current-send-codec");
-
- gst_element_post_message (GST_ELEMENT (self->priv->conference),
- gst_message_new_element (GST_OBJECT (self->priv->conference),
- gst_structure_new ("farsight-send-codec-changed",
- "session", FS_TYPE_SESSION, self,
- "codec", FS_TYPE_CODEC, codec,
- NULL)));
-
- fs_codec_destroy (codec);
-}
-
static void
pad_block_do_nothing (GstPad *pad, gboolean blocked, gpointer user_data)
{
@@ -3287,72 +3350,30 @@ _send_src_pad_blocked_callback (GstPad *pad, gboolean blocked,
g_clear_error (&error);
if (fs_codec_are_equal (codec_without_config, self->priv->current_send_codec))
- goto done;
-
-
- gst_element_set_locked_state (self->priv->send_codecbin, TRUE);
- if (gst_element_set_state (self->priv->send_codecbin, GST_STATE_NULL) !=
- GST_STATE_CHANGE_SUCCESS)
- {
- gst_element_set_locked_state (self->priv->send_codecbin, FALSE);
- fs_session_emit_error (FS_SESSION (self), FS_ERROR_INTERNAL,
- "Could not stop the codec bin",
- "Setting the codec bin to NULL did not succeed" );
- goto done;
- }
-
- gst_bin_remove (GST_BIN (self->priv->conference), self->priv->send_codecbin);
- self->priv->send_codecbin = NULL;
-
- fs_codec_destroy (self->priv->current_send_codec);
- self->priv->current_send_codec = NULL;
+ goto done_locked;
- while (self->priv->extra_send_capsfilters)
- {
- GstElement *cf = self->priv->extra_send_capsfilters->data;
- GstPad *ourpad = gst_element_get_static_pad (cf, "src");
- GstPad *pad = NULL;
-
- if (ourpad)
- {
- pad = gst_pad_get_peer (ourpad);
- if (pad)
- {
- gst_pad_set_active (pad, FALSE);
- gst_element_release_request_pad (self->priv->rtpmuxer, pad);
- gst_object_unref (pad);
- }
- gst_object_unref (ourpad);
- }
+ FS_RTP_SESSION_UNLOCK (self);
- gst_element_set_locked_state (cf, TRUE);
- gst_element_set_state (cf, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (self->priv->conference), cf);
+ g_object_set (self->priv->media_sink_valve, "drop", TRUE, NULL);
- self->priv->extra_send_capsfilters = g_list_delete_link (
- self->priv->extra_send_capsfilters,
- self->priv->extra_send_capsfilters);
- }
+ if (!fs_rtp_session_remove_send_codec_bin (self, codec_without_config,
+ TRUE))
+ goto done;
+ FS_RTP_SESSION_LOCK (self);
+ /* We have to re-fetch the ca because we lifted the lock */
+ ca = fs_rtp_session_select_send_codec_locked (self, &error);
- self->priv->extra_sources = fs_rtp_special_sources_remove (
- self->priv->extra_sources,
- self->priv->codec_associations, codec_without_config,
- GST_ELEMENT (self->priv->conference),
- self->priv->rtpmuxer);
- if (error)
+ if (!ca)
{
- fs_session_emit_error (FS_SESSION (self), FS_ERROR_INTERNAL,
- "Could not remove unused special sources",
- "Could not remove unused special sources");
- goto done;
+ fs_session_emit_error (FS_SESSION (self), error->code,
+ "Could not select a new send codec", error->message);
+ goto done_locked;
}
- /*
- * Lets reset the clock-rate (because rtpmuxer saves it.. )
- */
- g_object_set (self->priv->rtpmuxer, "clock-rate", 0, NULL);
+ codec_without_config = codec_copy_without_config (ca->codec);
+ g_clear_error (&error);
if (!fs_rtp_session_add_send_codec_bin_unlock (self, codec_without_config,
ca, &error))
@@ -3369,13 +3390,13 @@ _send_src_pad_blocked_callback (GstPad *pad, gboolean blocked,
GST_ELEMENT (self->priv->conference),
self->priv->rtpmuxer);
if (error)
- {
fs_session_emit_error (FS_SESSION (self), FS_ERROR_INTERNAL,
"Could not create special sources",
"Could not create special sources");
- goto done;
- }
+ done_locked:
+
+ FS_RTP_SESSION_UNLOCK (self);
done:
g_clear_error (&error);
@@ -3388,47 +3409,23 @@ _send_src_pad_blocked_callback (GstPad *pad, gboolean blocked,
fs_codec_destroy (codec_without_config);
gst_pad_set_blocked_async (pad, FALSE, pad_block_do_nothing, NULL);
-
- FS_RTP_SESSION_UNLOCK (self);
}
/**
- * fs_rtp_session_verify_send_codec_bin_locked:
+ * fs_rtp_session_verify_send_codec_bin:
*
* Verify that the current send codec is still valid and if it is not
* do whats required to have the right one be used.
*
- * Must be called with the FsRtpSession lock taken
+ * Does not care about locks
*
- * Returns: TRUE if it succeeds, FALSE on an error
*/
-static gboolean
-fs_rtp_session_verify_send_codec_bin_locked (FsRtpSession *self, GError **error)
+static void
+fs_rtp_session_verify_send_codec_bin (FsRtpSession *self)
{
- CodecAssociation *ca = NULL;
- FsCodec *codec_without_config = NULL;
-
- ca = fs_rtp_session_select_send_codec_locked (self, error);
- if (!ca)
- return FALSE;
-
- codec_without_config = codec_copy_without_config (ca->codec);
-
- if (self->priv->current_send_codec)
- {
- if (fs_codec_are_equal (codec_without_config,
- self->priv->current_send_codec))
- goto done;
- }
-
gst_pad_set_blocked_async (self->priv->send_tee_media_pad, TRUE,
_send_src_pad_blocked_callback, self);
-
- done:
-
- fs_codec_destroy (codec_without_config);
- return TRUE;
}
/*
--
1.5.6.5
More information about the farsight-commits
mailing list