[farsight2/master] Import improved version of create_codec_bin
Olivier Crête
olivier.crete at collabora.co.uk
Tue Dec 23 15:19:55 PST 2008
---
gst/fsrtpconference/fs-rtp-session.c | 189 ++++++++++++++++++++++++++++++++++
1 files changed, 189 insertions(+), 0 deletions(-)
diff --git a/gst/fsrtpconference/fs-rtp-session.c b/gst/fsrtpconference/fs-rtp-session.c
index 51e9100..89059bf 100644
--- a/gst/fsrtpconference/fs-rtp-session.c
+++ b/gst/fsrtpconference/fs-rtp-session.c
@@ -1381,3 +1381,192 @@ fs_rtp_session_new_recv_pad (FsRtpSession *session, GstPad *new_pad,
}
}
+
+
+static gboolean
+_g_object_has_property (GObject *object, const gchar *property)
+{
+ GObjectClass *klass;
+
+ klass = G_OBJECT_GET_CLASS (object);
+ return NULL != g_object_class_find_property (klass, property);
+}
+
+
+static gboolean
+_create_ghost_pad (GstElement *current_element, const gchar *padname, GstElement
+ *codec_bin, GError **error)
+{
+ GstPad *ghostpad;
+ GstPad *pad = gst_element_get_static_pad (current_element, padname);
+ gboolean ret = FALSE;
+
+ if (!pad) {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not find the %s on the element", padname);
+ return FALSE;
+ }
+
+ ghostpad = gst_ghost_pad_new (padname, pad);
+ if (!ghostpad) {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not create a ghost pad for pad %s", padname);
+ goto done;
+ }
+
+ if (!gst_pad_set_active (ghostpad, TRUE)) {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not active ghostpad %s", padname);
+ gst_object_unref (ghostpad);
+ goto done;
+ }
+
+ if (!gst_element_add_pad (codec_bin, ghostpad))
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not add ghostpad %s to the codec bin", padname);
+
+ ret = TRUE;
+ done:
+ gst_object_unref (pad);
+
+ return ret;
+}
+
+GstElement *
+_create_codec_bin (CodecAssociation *codec_association, gchar *name,
+ gboolean is_send, GError **error)
+{
+ GList *pipeline_factory = NULL;
+ GList *walk = NULL;
+ GstElement *codec_bin = NULL;
+ GstElement *current_element = NULL;
+ GstElement *previous_element = NULL;
+ gchar *direction_str = (is_send == TRUE) ? "send" : "receive";
+
+ if (is_send)
+ pipeline_factory = codec_association->blueprint->send_pipeline_factory;
+ else
+ pipeline_factory = codec_association->blueprint->receive_pipeline_factory;
+
+ g_debug ("creating %s codec bin for id %d, pipeline_factory %p",
+ direction_str, codec_association->codec->id, pipeline_factory);
+ codec_bin = gst_bin_new (name);
+
+ for (walk = g_list_first (pipeline_factory); walk; walk = g_list_next (walk))
+ {
+ if (g_list_next (g_list_first (walk->data))) {
+ /* We have to check some kind of configuration to see if we have a
+ favorite */
+ current_element = gst_element_factory_make ("fsselector", NULL);
+
+ if (!current_element) {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not create fsselector element");
+ goto error;
+ }
+
+ g_object_set (current_element, "factories", walk->data, NULL);
+ } else {
+ current_element =
+ gst_element_factory_create (
+ GST_ELEMENT_FACTORY (g_list_first (walk->data)->data), NULL);
+ if (!current_element) {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not create element for pt %d", codec_association->codec->id);
+ goto error;
+ }
+ }
+
+ if (!gst_bin_add (GST_BIN (codec_bin), current_element)) {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not add new element to %s codec_bin for pt %d",
+ direction_str, codec_association->codec->id);
+ goto error;
+ }
+
+ /* TODO: Element options
+ * set_options_on_element (walk->data, current_element);
+ */
+
+ /* queue delay to 0 on all depayloaders until I remove that property
+ * all-together */
+
+ if (_g_object_has_property (G_OBJECT (current_element), "queue-delay"))
+ g_object_set (G_OBJECT (current_element), "queue-delay", 0, NULL);
+
+ if (_g_object_has_property (G_OBJECT (current_element), "pt"))
+ g_object_set (current_element, "pt", codec_association->codec->id,
+ NULL);
+
+ /* Lets create the ghost pads on the codec bin */
+
+ if (g_list_first (pipeline_factory) == walk)
+ /* if its the first element of the codec bin */
+ if (!_create_ghost_pad (current_element, direction_str,
+ codec_bin, error))
+ goto error;
+
+ if (g_list_next (g_list_first (pipeline_factory)) == NULL)
+ /* if its the last element of the codec bin */
+ if (!_create_ghost_pad (current_element, direction_str, codec_bin, error))
+ goto error;
+
+
+ /* let's link them together using the specified media_caps if any
+ * this will ensure that multi-codec encoders/decoders will select the
+ * appropriate codec based on caps negotiation */
+ if (previous_element) {
+ GstPad *sinkpad;
+ GstPad *srcpad;
+ GstPadLinkReturn ret;
+
+ if (is_send)
+ sinkpad = gst_element_get_static_pad (current_element, "sink");
+ else
+ sinkpad = gst_element_get_static_pad (previous_element, "sink");
+
+ if (!sinkpad) {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not get the sink pad one of the elements in the %s codec bin"
+ " for pt %d", direction_str,
+ codec_association->codec->id);
+ goto error;
+ }
+
+
+ if (is_send)
+ srcpad = gst_element_get_static_pad (previous_element, "src");
+ else
+ srcpad = gst_element_get_static_pad (current_element, "src");
+
+ if (!srcpad) {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not get the src pad one of the elements in the %s codec bin"
+ " for pt %d", direction_str,
+ codec_association->codec->id);
+ gst_object_unref (sinkpad);
+ goto error;
+ }
+
+ ret = gst_pad_link (srcpad, sinkpad);
+
+ gst_object_unref (srcpad);
+ gst_object_unref (sinkpad);
+
+ if (GST_PAD_LINK_FAILED (ret)) {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not link element inside the %s codec bin for pt %d",
+ direction_str, codec_association->codec->id);
+ goto error;
+ }
+ }
+
+ previous_element = current_element;
+ }
+
+ return codec_bin;
+
+ error:
+ gst_object_unref (codec_bin);
+ return NULL;
+}
--
1.5.6.5
More information about the farsight-commits
mailing list