diff --git a/gst/rtpmux/Makefile.am b/gst/rtpmux/Makefile.am index 73973f5479..615981a8e7 100644 --- a/gst/rtpmux/Makefile.am +++ b/gst/rtpmux/Makefile.am @@ -1,6 +1,6 @@ plugin_LTLIBRARIES = libgstrtpmux.la -libgstrtpmux_la_SOURCES = gstrtpmux.c +libgstrtpmux_la_SOURCES = gstrtpmux.c gstrtpmux.h libgstrtpmux_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(ERROR_CFLAGS) -DEXTERN_BUF -DRTP_SUPPORT libgstrtpmux_la_LIBADD = $(GST_LIBS_LIBS) diff --git a/gst/rtpmux/gstrtpmux.c b/gst/rtpmux/gstrtpmux.c index 0e0593d95b..47a285b171 100644 --- a/gst/rtpmux/gstrtpmux.c +++ b/gst/rtpmux/gstrtpmux.c @@ -38,47 +38,12 @@ #include #include - +#include #include GST_DEBUG_CATEGORY_STATIC (gst_rtp_mux_debug); #define GST_CAT_DEFAULT gst_rtp_mux_debug -#define GST_TYPE_RTP_MUX (gst_rtp_mux_get_type()) -#define GST_RTP_MUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MUX, GstRTPMux)) -#define GST_RTP_MUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MUX, GstRTPMux)) -#define GST_IS_RTP_MUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MUX)) -#define GST_IS_RTP_MUX_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MUX)) - -typedef struct _GstRTPMux GstRTPMux; -typedef struct _GstRTPMuxClass GstRTPMuxClass; - -/** - * GstRTPMux: - * - * The opaque #GstRTPMux structure. - */ -struct _GstRTPMux -{ - GstElement element; - - /* pad */ - GstPad *srcpad; - - /* sinkpads */ - gint numpads; - GstPad *special_pad; - - guint16 seqnum_base; - gint16 seqnum_offset; - guint16 seqnum; -}; - -struct _GstRTPMuxClass -{ - GstElementClass parent_class; -}; - /* elementfactory information */ static const GstElementDetails gst_rtp_mux_details = GST_ELEMENT_DETAILS ("RTP muxer", @@ -114,8 +79,6 @@ static void gst_rtp_mux_init (GstRTPMux * rtp_mux); static void gst_rtp_mux_finalize (GObject * object); -static gboolean gst_rtp_mux_handle_sink_event (GstPad * pad, - GstEvent * event); static GstPad *gst_rtp_mux_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name); static GstFlowReturn gst_rtp_mux_chain (GstPad * pad, @@ -196,6 +159,8 @@ gst_rtp_mux_class_init (GstRTPMuxClass * klass) gstelement_class->request_new_pad = gst_rtp_mux_request_new_pad; gstelement_class->change_state = gst_rtp_mux_change_state; + + klass->chain_func = gst_rtp_mux_chain; } static void @@ -227,39 +192,43 @@ gst_rtp_mux_request_new_pad (GstElement * element, { GstRTPMux *rtp_mux; GstPad *newpad; - GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); + GstRTPMuxClass *klass; + GstPadTemplate * class_templ; g_return_val_if_fail (templ != NULL, NULL); + g_return_val_if_fail (GST_IS_RTP_MUX (element), NULL); rtp_mux = GST_RTP_MUX (element); + klass = GST_RTP_MUX_GET_CLASS (rtp_mux); if (templ->direction != GST_PAD_SINK) { GST_WARNING_OBJECT (rtp_mux, "request pad that is not a SINK pad"); return NULL; } - g_return_val_if_fail (GST_IS_RTP_MUX (element), NULL); + class_templ = + gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink_%d"); - if (templ == gst_element_class_get_pad_template (klass, "sink_%d")) { + if (templ == class_templ) { gchar *name; - GST_OBJECT_LOCK (rtp_mux); /* create new pad with the name */ name = g_strdup_printf ("sink_%02d", rtp_mux->numpads); newpad = gst_pad_new_from_template (templ, name); g_free (name); rtp_mux->numpads++; - GST_OBJECT_UNLOCK (rtp_mux); } else { GST_WARNING_OBJECT (rtp_mux, "this is not our template!\n"); return NULL; } /* setup some pad functions */ - gst_pad_set_chain_function (newpad, gst_rtp_mux_chain); gst_pad_set_setcaps_function (newpad, gst_rtp_mux_setcaps); - gst_pad_set_event_function (newpad, gst_rtp_mux_handle_sink_event); + if (klass->chain_func) + gst_pad_set_chain_function (newpad, klass->chain_func); + if (klass->sink_event_func) + gst_pad_set_event_function (newpad, klass->sink_event_func); /* dd the pad to the element */ gst_element_add_pad (element, newpad); @@ -271,33 +240,17 @@ static GstFlowReturn gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer) { GstRTPMux *rtp_mux; - gboolean drop = FALSE; GstFlowReturn ret; rtp_mux = GST_RTP_MUX (gst_pad_get_parent (pad)); - GST_OBJECT_LOCK (rtp_mux); - if (rtp_mux->special_pad != NULL && - rtp_mux->special_pad != pad) { - drop = TRUE; - } + rtp_mux->seqnum++; + GST_LOG_OBJECT (rtp_mux, "setting RTP seqnum %d", rtp_mux->seqnum); + gst_rtp_buffer_set_seq (buffer, rtp_mux->seqnum); + GST_DEBUG_OBJECT (rtp_mux, "Pushing packet size %d, seq=%d, ts=%u", + GST_BUFFER_SIZE (buffer), rtp_mux->seqnum - 1); - if (drop) { - gst_buffer_unref (buffer); - ret = GST_FLOW_OK; - GST_OBJECT_UNLOCK (rtp_mux); - } - - else { - rtp_mux->seqnum++; - GST_LOG_OBJECT (rtp_mux, "setting RTP seqnum %d", rtp_mux->seqnum); - gst_rtp_buffer_set_seq (buffer, rtp_mux->seqnum); - GST_DEBUG_OBJECT (rtp_mux, "Pushing packet size %d, seq=%d, ts=%u", - GST_BUFFER_SIZE (buffer), rtp_mux->seqnum - 1); - - GST_OBJECT_UNLOCK (rtp_mux); - ret = gst_pad_push (rtp_mux->srcpad, buffer); - } + ret = gst_pad_push (rtp_mux->srcpad, buffer); gst_object_unref (rtp_mux); return ret; @@ -338,74 +291,6 @@ gst_rtp_mux_setcaps (GstPad *pad, GstCaps *caps) return TRUE; } -static gboolean -gst_rtp_mux_handle_sink_event (GstPad * pad, GstEvent * event) -{ - GstRTPMux *rtp_mux; - GstEventType type; - - rtp_mux = GST_RTP_MUX (gst_pad_get_parent (pad)); - - type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN; - - switch (type) { - case GST_EVENT_CUSTOM_DOWNSTREAM_OOB: - { - const GstStructure *structure; - - structure = gst_event_get_structure (event); - /* FIXME: is this event generic enough to be given a generic name? */ - if (structure && gst_structure_has_name (structure, "stream-lock")) { - gboolean lock; - - if (!gst_structure_get_boolean (structure, "lock", &lock)) - break; - - GST_OBJECT_LOCK (rtp_mux); - if (lock) { - if (rtp_mux->special_pad != NULL) { - GST_WARNING_OBJECT (rtp_mux, - "Stream lock already acquired by pad %s", - GST_ELEMENT_NAME (rtp_mux->special_pad)); - } - - else - rtp_mux->special_pad = gst_object_ref (pad); - } - - else { - if (rtp_mux->special_pad == NULL) { - GST_WARNING_OBJECT (rtp_mux, - "Stream lock not acquired, can't release it"); - } - - else if (pad != rtp_mux->special_pad) { - GST_WARNING_OBJECT (rtp_mux, - "pad %s attempted to release Stream lock" - " which was acquired by pad %s", GST_ELEMENT_NAME (pad), - GST_ELEMENT_NAME (rtp_mux->special_pad)); - } - - else { - gst_object_unref (rtp_mux->special_pad); - rtp_mux->special_pad = NULL; - } - } - - GST_OBJECT_UNLOCK (rtp_mux); - } - - break; - } - default: - break; - } - - gst_object_unref (rtp_mux); - - return gst_pad_event_default (pad, event); -} - static void gst_rtp_mux_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) diff --git a/gst/rtpmux/gstrtpmux.h b/gst/rtpmux/gstrtpmux.h new file mode 100644 index 0000000000..b4b7bc2fc6 --- /dev/null +++ b/gst/rtpmux/gstrtpmux.h @@ -0,0 +1,76 @@ +/* RTP muxer element for GStreamer + * + * gstrtpmux.h: + * + * Copyright (C) <2007> Nokia Corporation. + * Contact: Zeeshan Ali + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000,2005 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_RTP_MUX_H__ +#define __GST_RTP_MUX_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_RTP_MUX (gst_rtp_mux_get_type()) +#define GST_RTP_MUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MUX, GstRTPMux)) +#define GST_RTP_MUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MUX, GstRTPMux)) +#define GST_RTP_MUX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTP_MUX, GstRTPMuxClass)) +#define GST_IS_RTP_MUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MUX)) +#define GST_IS_RTP_MUX_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MUX)) + +typedef struct _GstRTPMux GstRTPMux; +typedef struct _GstRTPMuxClass GstRTPMuxClass; + +/** + * GstRTPMux: + * + * The opaque #GstRTPMux structure. + */ +struct _GstRTPMux +{ + GstElement element; + + /* pad */ + GstPad *srcpad; + + /* sinkpads */ + gint numpads; + + guint16 seqnum_base; + gint16 seqnum_offset; + guint16 seqnum; +}; + +struct _GstRTPMuxClass +{ + GstElementClass parent_class; + + GstFlowReturn (* chain_func) (GstPad * pad, GstBuffer * buffer); + gboolean (* sink_event_func) (GstPad * pad, GstEvent * event); +}; + +GType gst_rtp_mux_get_type (void); + +G_END_DECLS + +#endif /* __GST_RTP_MUX_H__ */ +