From a216b903637a638dcc9e1484aecfeee1f28a1a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Sun, 9 Oct 2011 17:30:09 -0400 Subject: [PATCH] rtpsubstream: Restore the capsfilter for the recv caps --- gst/fsrtpconference/fs-rtp-substream.c | 77 ++++++++++++++++++++++++++++++- 1 files changed, 74 insertions(+), 3 deletions(-) diff --git a/gst/fsrtpconference/fs-rtp-substream.c b/gst/fsrtpconference/fs-rtp-substream.c index 084229e..c5c8183 100644 --- a/gst/fsrtpconference/fs-rtp-substream.c +++ b/gst/fsrtpconference/fs-rtp-substream.c @@ -44,7 +44,7 @@ * * This object controls a part of the receive pipeline, with the following shape * - * rtpbin_pad -> input_valve -> codecbin -> output_valve -> output_ghostad + * rtpbin_pad -> input_valve -> capsfilter -> codecbin -> output_valve -> output_ghostad * */ @@ -92,6 +92,8 @@ struct _FsRtpSubStreamPrivate { GstElement *input_valve; GstElement *output_valve; + GstElement *capsfilter; + /* This only exists if the codec is valid, * otherwise the rtpbin_pad is blocked */ /* Protected by the session mutex */ @@ -602,6 +604,36 @@ fs_rtp_sub_stream_constructed (GObject *object) return; } + tmp = g_strdup_printf ("recv_capsfilter_%d_%d_%d", self->priv->session->id, + self->ssrc, self->pt); + self->priv->capsfilter = gst_element_factory_make ("capsfilter", tmp); + g_free (tmp); + + if (!self->priv->capsfilter) { + self->priv->construction_error = g_error_new (FS_ERROR, + FS_ERROR_CONSTRUCTION, "Could not create a capsfilter element for" + " session substream with ssrc: %u and pt:%d", self->ssrc, + self->pt); + return; + } + + if (!gst_bin_add (GST_BIN (self->priv->conference), self->priv->capsfilter)) { + self->priv->construction_error = g_error_new (FS_ERROR, + FS_ERROR_CONSTRUCTION, "Could not add the capsfilter element for session" + " substream with ssrc: %u and pt:%d to the conference bin", + self->ssrc, self->pt); + return; + } + + if (gst_element_set_state (self->priv->capsfilter, GST_STATE_PLAYING) == + GST_STATE_CHANGE_FAILURE) { + self->priv->construction_error = g_error_new (FS_ERROR, + FS_ERROR_CONSTRUCTION, "Could not set the capsfilter element for session" + " substream with ssrc: %u and pt:%d to the playing state", + self->ssrc, self->pt); + return; + } + tmp = g_strdup_printf ("input_recv_valve_%d_%d_%d", self->priv->session->id, self->ssrc, self->pt); self->priv->input_valve = gst_element_factory_make ("valve", tmp); @@ -633,6 +665,14 @@ fs_rtp_sub_stream_constructed (GObject *object) return; } + if (!gst_element_link (self->priv->input_valve, self->priv->capsfilter)) + { + self->priv->construction_error = g_error_new (FS_ERROR, + FS_ERROR_CONSTRUCTION, "Could not link the input valve" + " and the capsfilter"); + return; + } + valve_sink_pad = gst_element_get_static_pad (self->priv->input_valve, "sink"); if (!valve_sink_pad) @@ -693,6 +733,13 @@ fs_rtp_sub_stream_dispose (GObject *object) self->priv->codecbin = NULL; } + if (self->priv->capsfilter) { + gst_element_set_locked_state (self->priv->capsfilter, TRUE); + gst_element_set_state (self->priv->capsfilter, GST_STATE_NULL); + gst_bin_remove (GST_BIN (self->priv->conference), self->priv->capsfilter); + self->priv->capsfilter = NULL; + } + if (self->priv->input_valve) { gst_element_set_locked_state (self->priv->input_valve, TRUE); gst_element_set_state (self->priv->input_valve, GST_STATE_NULL); @@ -913,11 +960,11 @@ fs_rtp_sub_stream_set_codecbin (FsRtpSubStream *substream, goto error; } - if (!gst_element_link_pads (substream->priv->input_valve, "src", + if (!gst_element_link_pads (substream->priv->capsfilter, "src", codecbin, "sink")) { g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION, - "Could not link the receive input valve and the codecbin for pt %d", + "Could not link the receive capsfilter and the codecbin for pt %d", substream->pt); goto error; } @@ -1041,6 +1088,12 @@ fs_rtp_sub_stream_stop (FsRtpSubStream *substream) gst_element_set_state (substream->priv->codecbin, GST_STATE_NULL); } + if (substream->priv->capsfilter) + { + gst_element_set_locked_state (substream->priv->capsfilter, TRUE); + gst_element_set_state (substream->priv->capsfilter, GST_STATE_NULL); + } + if (substream->priv->input_valve) { gst_element_set_locked_state (substream->priv->input_valve, TRUE); @@ -1299,6 +1352,24 @@ _rtpbin_pad_blocked_callback (GstPad *pad, gboolean blocked, gpointer user_data) if (error) goto error; + FS_RTP_SESSION_LOCK (substream->priv->session); + if (codec && + (!substream->codec || !fs_codec_are_equal (codec, substream->codec))) + { + GstCaps *caps; + gchar *tmp; + + caps = fs_codec_to_gst_caps (codec); + tmp = gst_caps_to_string (caps); + GST_DEBUG ("Setting caps %s on recv substream", tmp); + g_free (tmp); + g_object_set (substream->priv->capsfilter, "caps", caps, NULL); + + fs_rtp_sub_stream_add_probe_locked (substream); + } + FS_RTP_SESSION_UNLOCK (substream->priv->session); + + if (codecbin) if (!fs_rtp_sub_stream_set_codecbin (substream, codec, codecbin, new_builder_hash, &error)) -- 1.7.6.4