[farsight2/master] Add functions to create/destroy nice sinks/sources
Olivier Crête
olivier.crete at collabora.co.uk
Tue Dec 23 15:26:15 PST 2008
---
transmitters/nice/fs-nice-transmitter.c | 220 +++++++++++++++++++++++++++++++
transmitters/nice/fs-nice-transmitter.h | 12 ++
2 files changed, 232 insertions(+), 0 deletions(-)
diff --git a/transmitters/nice/fs-nice-transmitter.c b/transmitters/nice/fs-nice-transmitter.c
index a90464b..e1332c9 100644
--- a/transmitters/nice/fs-nice-transmitter.c
+++ b/transmitters/nice/fs-nice-transmitter.c
@@ -796,3 +796,223 @@ fs_nice_transmitter_get_stream_transmitter_type (
{
return FS_TYPE_NICE_STREAM_TRANSMITTER;
}
+
+
+
+static GstElement *
+_create_sinksource (
+ gchar *elementname,
+ GstBin *bin,
+ GstElement *teefunnel,
+ NiceAgent *agent,
+ guint stream_id,
+ guint component_id,
+ GstPadDirection direction,
+ GstPad **requested_pad,
+ GError **error)
+{
+ GstElement *elem;
+ GstPadLinkReturn ret;
+ GstPad *elempad = NULL;
+ GstStateChangeReturn state_ret;
+
+ g_assert (direction == GST_PAD_SINK || direction == GST_PAD_SRC);
+
+ elem = gst_element_factory_make (elementname, NULL);
+ if (!elem)
+ {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not create the %s element", elementname);
+ return NULL;
+ }
+
+ g_object_set (elem,
+ "agent", agent,
+ "stream", stream_id,
+ "component", component_id,
+ NULL);
+
+ if (!gst_bin_add (bin, elem))
+ {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not add the %s element to the gst %s bin", elementname,
+ (direction == GST_PAD_SINK) ? "sink" : "src");
+ gst_object_unref (elem);
+ return NULL;
+ }
+
+ if (direction == GST_PAD_SINK)
+ *requested_pad = gst_element_get_request_pad (teefunnel, "src%d");
+ else
+ *requested_pad = gst_element_get_request_pad (teefunnel, "sink%d");
+
+ if (!*requested_pad)
+ {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not get the %s request pad from the %s",
+ (direction == GST_PAD_SINK) ? "src" : "sink",
+ (direction == GST_PAD_SINK) ? "tee" : "funnel");
+ goto error;
+ }
+
+ if (direction == GST_PAD_SINK)
+ elempad = gst_element_get_static_pad (elem, "sink");
+ else
+ elempad = gst_element_get_static_pad (elem, "src");
+
+ if (direction == GST_PAD_SINK)
+ ret = gst_pad_link (*requested_pad, elempad);
+ else
+ ret = gst_pad_link (elempad, *requested_pad);
+
+ gst_object_unref (elempad);
+
+ if (GST_PAD_LINK_FAILED(ret))
+ {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not link the new element %s (%d)", elementname, ret);
+ goto error;
+ }
+
+ if (!gst_element_sync_state_with_parent (elem))
+ {
+ g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
+ "Could not sync the state of the new %s with its parent",
+ elementname);
+ goto error;
+ }
+
+ return elem;
+
+ error:
+
+ gst_element_set_locked_state (elem, TRUE);
+ state_ret = gst_element_set_state (elem, GST_STATE_NULL);
+ if (state_ret != GST_STATE_CHANGE_SUCCESS)
+ GST_ERROR ("On error, could not reset %s to state NULL (%s)", elementname,
+ gst_element_state_change_return_get_name (state_ret));
+ if (!gst_bin_remove (bin, elem))
+ GST_ERROR ("Could not remove element %s from bin on error", elementname);
+
+ if (elempad)
+ gst_object_unref (elempad);
+
+ return NULL;
+}
+
+struct _NiceGstStream {
+ GstElement **nicesrcs;
+ GstElement **nicesinks;
+
+ GstPad **requested_funnel_pads;
+ GstPad **requested_tee_pads;
+};
+
+NiceGstStream *
+fs_nice_transmitter_add_gst_stream (FsNiceTransmitter *self,
+ guint stream_id,
+ GError **error)
+{
+ guint c;
+ NiceGstStream *ns = NULL;
+
+ ns = g_new0 (NiceGstStream, 1);
+ ns->nicesrcs = g_new0 (GstElement *, self->components + 1);
+ ns->nicesinks = g_new0 (GstElement *, self->components + 1);
+ ns->requested_tee_pads = g_new0 (GstPad *, self->components + 1);
+ ns->requested_funnel_pads = g_new0 (GstPad *, self->components + 1);
+
+ for (c = 1; c <= self->components; c++)
+ {
+ ns->nicesrcs[c] = _create_sinksource ("nicesrc",
+ GST_BIN (self->priv->gst_src),
+ self->priv->src_funnels[c],
+ self->agent,
+ stream_id,
+ c,
+ GST_PAD_SRC,
+ &ns->requested_funnel_pads[c],
+ error);
+
+ if (ns->nicesrcs[c] == NULL)
+ goto error;
+
+ ns->nicesinks[c] = _create_sinksource ("nicesink",
+ GST_BIN (self->priv->gst_sink),
+ self->priv->sink_tees[c],
+ self->agent,
+ stream_id,
+ c,
+ GST_PAD_SINK,
+ &ns->requested_tee_pads[c],
+ error);
+
+ if (ns->nicesinks[c] == NULL)
+ goto error;
+
+ g_object_set (ns->nicesinks[c],
+ "async", FALSE,
+ "sync", FALSE,
+ NULL);
+ }
+
+ return ns;
+
+ error:
+ fs_nice_transmitter_free_gst_stream (self, ns);
+ return NULL;
+}
+
+void
+fs_nice_transmitter_free_gst_stream (FsNiceTransmitter *self,
+ NiceGstStream *ns)
+{
+ guint c;
+
+ for (c = 1; c <= self->components; c++)
+ {
+ if (ns->nicesrcs[c])
+ {
+ GstStateChangeReturn ret;
+ gst_element_set_locked_state (ns->nicesrcs[c], TRUE);
+ ret = gst_element_set_state (ns->nicesrcs[c], GST_STATE_NULL);
+ if (ret != GST_STATE_CHANGE_SUCCESS)
+ GST_ERROR ("Error changing state of nicesrc: %s",
+ gst_element_state_change_return_get_name (ret));
+ if (!gst_bin_remove (GST_BIN (self->priv->gst_src), ns->nicesrcs[c]))
+ GST_ERROR ("Could not remove nicesrc element from transmitter source");
+ }
+
+ if (ns->requested_funnel_pads[c])
+ {
+ gst_element_release_request_pad (self->priv->src_funnels[c],
+ ns->requested_funnel_pads[c]);
+ gst_object_unref (ns->requested_funnel_pads[c]);
+ }
+
+ if (ns->nicesinks[c])
+ {
+ GstStateChangeReturn ret;
+ gst_element_set_locked_state (ns->nicesinks[c], TRUE);
+ ret = gst_element_set_state (ns->nicesinks[c], GST_STATE_NULL);
+ if (ret != GST_STATE_CHANGE_SUCCESS)
+ GST_ERROR ("Error changing state of nicesink: %s",
+ gst_element_state_change_return_get_name (ret));
+ if (!gst_bin_remove (GST_BIN (self->priv->gst_sink), ns->nicesinks[c]))
+ GST_ERROR ("Could not remove nicesink element from transmitter source");
+ }
+
+ if (ns->requested_tee_pads[c])
+ {
+ gst_element_release_request_pad (self->priv->sink_tees[c],
+ ns->requested_tee_pads[c]);
+ gst_object_unref (ns->requested_tee_pads[c]);
+ }
+ }
+
+ g_free (ns->nicesrcs);
+ g_free (ns->nicesinks);
+ g_free (ns->requested_tee_pads);
+ g_free (ns->requested_funnel_pads);
+ g_free (ns);
+}
diff --git a/transmitters/nice/fs-nice-transmitter.h b/transmitters/nice/fs-nice-transmitter.h
index 5916590..81f924a 100644
--- a/transmitters/nice/fs-nice-transmitter.h
+++ b/transmitters/nice/fs-nice-transmitter.h
@@ -88,6 +88,18 @@ struct _FsNiceTransmitter
GType fs_nice_transmitter_get_type (void);
+struct _NiceGstStream;
+typedef struct _NiceGstStream NiceGstStream;
+
+NiceGstStream *fs_nice_transmitter_add_gst_stream (FsNiceTransmitter *self,
+ guint stream_id,
+ GError **error);
+
+void fs_nice_transmitter_free_gst_stream (FsNiceTransmitter *self,
+ NiceGstStream *ns);
+
+
+
G_END_DECLS
#endif /* __FS_NICE_TRANSMITTER_H__ */
--
1.5.6.5
More information about the farsight-commits
mailing list