diff options
author | Olivier CrĂȘte <olivier.crete@collabora.co.uk> | 2011-04-14 14:34:26 -0400 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2011-08-24 12:24:17 -0400 |
commit | 859b8ebfc95d54a0011ab44af4d5da283a7d3651 (patch) | |
tree | 83509e379452cb8c6adb506442e79b2e8424d467 | |
parent | 38aaf7cbabd3358b32db191993b3c30cc4ee8620 (diff) |
rtpdtmfmux: Add last-stop to dtmf-event upstream events
Add the running time of the last outputted buffer to the
upstream "dtmf-event" events so that the dtmf source does not
leave a gap.
-rw-r--r-- | gst/rtpmux/gstrtpdtmfmux.c | 25 | ||||
-rw-r--r-- | gst/rtpmux/gstrtpmux.c | 72 | ||||
-rw-r--r-- | gst/rtpmux/gstrtpmux.h | 6 |
3 files changed, 89 insertions, 14 deletions
diff --git a/gst/rtpmux/gstrtpdtmfmux.c b/gst/rtpmux/gstrtpdtmfmux.c index f62c6263d..97ffacd2f 100644 --- a/gst/rtpmux/gstrtpdtmfmux.c +++ b/gst/rtpmux/gstrtpdtmfmux.c @@ -64,6 +64,8 @@ static GstStateChangeReturn gst_rtp_dtmf_mux_change_state (GstElement * element, static gboolean gst_rtp_dtmf_mux_accept_buffer_locked (GstRTPMux * rtp_mux, GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer); +static gboolean gst_rtp_dtmf_mux_src_event (GstRTPMux * rtp_mux, + GstEvent * event); GST_BOILERPLATE (GstRTPDTMFMux, gst_rtp_dtmf_mux, GstRTPMux, GST_TYPE_RTP_MUX); @@ -100,6 +102,7 @@ gst_rtp_dtmf_mux_class_init (GstRTPDTMFMuxClass * klass) gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_dtmf_mux_change_state); gstrtpmux_class->accept_buffer_locked = gst_rtp_dtmf_mux_accept_buffer_locked; + gstrtpmux_class->src_event = gst_rtp_dtmf_mux_src_event; } static gboolean @@ -173,6 +176,28 @@ gst_rtp_dtmf_mux_request_new_pad (GstElement * element, GstPadTemplate * templ, return pad; } +static gboolean +gst_rtp_dtmf_mux_src_event (GstRTPMux * rtp_mux, GstEvent * event) +{ + if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_UPSTREAM) { + const GstStructure *s = gst_event_get_structure (event); + + if (s && gst_structure_has_name (s, "dtmf-event")) { + GST_OBJECT_LOCK (rtp_mux); + if (GST_CLOCK_TIME_IS_VALID (rtp_mux->last_stop)) { + event = (GstEvent *) + gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (event)); + s = gst_event_get_structure (event); + gst_structure_set ((GstStructure *) s, + "last-stop", G_TYPE_UINT64, rtp_mux->last_stop, NULL); + } + GST_OBJECT_UNLOCK (rtp_mux); + } + } + + return GST_RTP_MUX_CLASS (parent_class)->src_event (rtp_mux, event); +} + static GstStateChangeReturn gst_rtp_dtmf_mux_change_state (GstElement * element, GstStateChange transition) diff --git a/gst/rtpmux/gstrtpmux.c b/gst/rtpmux/gstrtpmux.c index 57929ec60..f86fd5d6b 100644 --- a/gst/rtpmux/gstrtpmux.c +++ b/gst/rtpmux/gstrtpmux.c @@ -107,6 +107,9 @@ static void gst_rtp_mux_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_rtp_mux_dispose (GObject * object); +static gboolean gst_rtp_mux_src_event_real (GstRTPMux *rtp_mux, + GstEvent * event); + GST_BOILERPLATE (GstRTPMux, gst_rtp_mux, GstElement, GST_TYPE_ELEMENT); static void @@ -137,6 +140,8 @@ gst_rtp_mux_class_init (GstRTPMuxClass * klass) gobject_class->set_property = gst_rtp_mux_set_property; gobject_class->dispose = gst_rtp_mux_dispose; + klass->src_event = gst_rtp_mux_src_event_real; + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TIMESTAMP_OFFSET, g_param_spec_int ("timestamp-offset", "Timestamp Offset", @@ -183,16 +188,30 @@ restart: static gboolean gst_rtp_mux_src_event (GstPad * pad, GstEvent * event) { - GstElement *rtp_mux; + GstRTPMux *rtp_mux; + GstRTPMuxClass *klass; + gboolean ret = FALSE; + + rtp_mux = (GstRTPMux *) gst_pad_get_parent_element (pad); + g_return_val_if_fail (rtp_mux != NULL, FALSE); + klass = GST_RTP_MUX_GET_CLASS (rtp_mux); + + ret = klass->src_event (rtp_mux, event); + + gst_object_unref (rtp_mux); + + return ret; +} + +static gboolean +gst_rtp_mux_src_event_real (GstRTPMux *rtp_mux, GstEvent * event) +{ GstIterator *iter; GstPad *sinkpad; gboolean result = FALSE; gboolean done = FALSE; - rtp_mux = gst_pad_get_parent_element (pad); - g_return_val_if_fail (rtp_mux != NULL, FALSE); - - iter = gst_element_iterate_sink_pads (rtp_mux); + iter = gst_element_iterate_sink_pads (GST_ELEMENT (rtp_mux)); while (!done) { switch (gst_iterator_next (iter, (gpointer) & sinkpad)) { @@ -213,7 +232,6 @@ gst_rtp_mux_src_event (GstPad * pad, GstEvent * event) } } gst_iterator_free (iter); - gst_object_unref (rtp_mux); gst_event_unref (event); return result; @@ -236,6 +254,7 @@ gst_rtp_mux_init (GstRTPMux * object, GstRTPMuxClass * g_class) object->seqnum_offset = DEFAULT_SEQNUM_OFFSET; object->segment_pending = TRUE; + object->last_stop = GST_CLOCK_TIME_NONE; } static void @@ -394,6 +413,20 @@ gst_rtp_mux_chain_list (GstPad * pad, GstBufferList * bufferlist) break; gst_buffer_list_iterator_take (it, rtpbuf); + + do { + if (GST_BUFFER_DURATION_IS_VALID (rtpbuf) && + GST_BUFFER_TIMESTAMP_IS_VALID (rtpbuf)) + rtp_mux->last_stop = GST_BUFFER_TIMESTAMP (rtpbuf) + + GST_BUFFER_DURATION (rtpbuf); + else + rtp_mux->last_stop = GST_CLOCK_TIME_NONE; + + gst_buffer_list_iterator_take (it, rtpbuf); + + } while ((rtpbuf = gst_buffer_list_iterator_next (it)) != NULL); + + } gst_buffer_list_iterator_free (it); @@ -456,15 +489,25 @@ gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer) drop = !process_buffer_locked (rtp_mux, padpriv, buffer); - if (!drop && rtp_mux->segment_pending) { - /* - * We set the start at 0, because we re-timestamps to the running time - */ - newseg_event = gst_event_new_new_segment_full (FALSE, 1.0, 1.0, - GST_FORMAT_TIME, 0, -1, 0); + if (!drop) { + if (rtp_mux->segment_pending) { + /* + * We set the start at 0, because we re-timestamps to the running time + */ + newseg_event = gst_event_new_new_segment_full (FALSE, 1.0, 1.0, + GST_FORMAT_TIME, 0, -1, 0); - rtp_mux->segment_pending = FALSE; + rtp_mux->segment_pending = FALSE; + } + + if (GST_BUFFER_DURATION_IS_VALID (buffer) && + GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) + rtp_mux->last_stop = GST_BUFFER_TIMESTAMP (buffer) + + GST_BUFFER_DURATION (buffer); + else + rtp_mux->last_stop = GST_CLOCK_TIME_NONE; } + GST_OBJECT_UNLOCK (rtp_mux); if (newseg_event) @@ -709,6 +752,7 @@ gst_rtp_mux_sink_event (GstPad * pad, GstEvent * event) GstRTPMuxPadPrivate *padpriv; GST_OBJECT_LOCK (mux); + mux->last_stop = GST_CLOCK_TIME_NONE; mux->segment_pending = TRUE; padpriv = gst_pad_get_element_private (pad); if (padpriv) @@ -801,6 +845,8 @@ gst_rtp_mux_ready_to_paused (GstRTPMux * rtp_mux) else rtp_mux->ts_base = rtp_mux->ts_offset; + rtp_mux->last_stop = GST_CLOCK_TIME_NONE; + GST_DEBUG_OBJECT (rtp_mux, "set clock-base to %u", rtp_mux->ts_base); GST_OBJECT_UNLOCK (rtp_mux); diff --git a/gst/rtpmux/gstrtpmux.h b/gst/rtpmux/gstrtpmux.h index 96513836d..7bfea60c0 100644 --- a/gst/rtpmux/gstrtpmux.h +++ b/gst/rtpmux/gstrtpmux.h @@ -31,7 +31,7 @@ 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_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MUX, GstRTPMuxClass)) #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)) @@ -74,6 +74,8 @@ struct _GstRTPMux guint current_ssrc; gboolean segment_pending; + + GstClockTime last_stop; }; struct _GstRTPMuxClass @@ -82,6 +84,8 @@ struct _GstRTPMuxClass gboolean (*accept_buffer_locked) (GstRTPMux *rtp_mux, GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer); + + gboolean (*src_event) (GstRTPMux *rtp_mux, GstEvent *event); }; |