mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 15:48:23 +00:00
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.
This commit is contained in:
parent
38aaf7cbab
commit
859b8ebfc9
3 changed files with 89 additions and 14 deletions
|
@ -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,
|
static gboolean gst_rtp_dtmf_mux_accept_buffer_locked (GstRTPMux * rtp_mux,
|
||||||
GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer);
|
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);
|
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 =
|
gstelement_class->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_rtp_dtmf_mux_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->accept_buffer_locked = gst_rtp_dtmf_mux_accept_buffer_locked;
|
||||||
|
gstrtpmux_class->src_event = gst_rtp_dtmf_mux_src_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -173,6 +176,28 @@ gst_rtp_dtmf_mux_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
||||||
return pad;
|
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
|
static GstStateChangeReturn
|
||||||
gst_rtp_dtmf_mux_change_state (GstElement * element, GstStateChange transition)
|
gst_rtp_dtmf_mux_change_state (GstElement * element, GstStateChange transition)
|
||||||
|
|
|
@ -107,6 +107,9 @@ static void gst_rtp_mux_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
static void gst_rtp_mux_dispose (GObject * object);
|
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);
|
GST_BOILERPLATE (GstRTPMux, gst_rtp_mux, GstElement, GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -137,6 +140,8 @@ gst_rtp_mux_class_init (GstRTPMuxClass * klass)
|
||||||
gobject_class->set_property = gst_rtp_mux_set_property;
|
gobject_class->set_property = gst_rtp_mux_set_property;
|
||||||
gobject_class->dispose = gst_rtp_mux_dispose;
|
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),
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
||||||
PROP_TIMESTAMP_OFFSET, g_param_spec_int ("timestamp-offset",
|
PROP_TIMESTAMP_OFFSET, g_param_spec_int ("timestamp-offset",
|
||||||
"Timestamp Offset",
|
"Timestamp Offset",
|
||||||
|
@ -183,16 +188,30 @@ restart:
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_rtp_mux_src_event (GstPad * pad, GstEvent * event)
|
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;
|
GstIterator *iter;
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
gboolean done = FALSE;
|
gboolean done = FALSE;
|
||||||
|
|
||||||
rtp_mux = gst_pad_get_parent_element (pad);
|
iter = gst_element_iterate_sink_pads (GST_ELEMENT (rtp_mux));
|
||||||
g_return_val_if_fail (rtp_mux != NULL, FALSE);
|
|
||||||
|
|
||||||
iter = gst_element_iterate_sink_pads (rtp_mux);
|
|
||||||
|
|
||||||
while (!done) {
|
while (!done) {
|
||||||
switch (gst_iterator_next (iter, (gpointer) & sinkpad)) {
|
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_iterator_free (iter);
|
||||||
gst_object_unref (rtp_mux);
|
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -236,6 +254,7 @@ gst_rtp_mux_init (GstRTPMux * object, GstRTPMuxClass * g_class)
|
||||||
object->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
|
object->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
|
||||||
|
|
||||||
object->segment_pending = TRUE;
|
object->segment_pending = TRUE;
|
||||||
|
object->last_stop = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -394,6 +413,20 @@ gst_rtp_mux_chain_list (GstPad * pad, GstBufferList * bufferlist)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
gst_buffer_list_iterator_take (it, rtpbuf);
|
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);
|
gst_buffer_list_iterator_free (it);
|
||||||
|
|
||||||
|
@ -456,7 +489,8 @@ gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
|
|
||||||
drop = !process_buffer_locked (rtp_mux, padpriv, buffer);
|
drop = !process_buffer_locked (rtp_mux, padpriv, buffer);
|
||||||
|
|
||||||
if (!drop && rtp_mux->segment_pending) {
|
if (!drop) {
|
||||||
|
if (rtp_mux->segment_pending) {
|
||||||
/*
|
/*
|
||||||
* We set the start at 0, because we re-timestamps to the running time
|
* We set the start at 0, because we re-timestamps to the running time
|
||||||
*/
|
*/
|
||||||
|
@ -465,6 +499,15 @@ gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
|
|
||||||
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);
|
GST_OBJECT_UNLOCK (rtp_mux);
|
||||||
|
|
||||||
if (newseg_event)
|
if (newseg_event)
|
||||||
|
@ -709,6 +752,7 @@ gst_rtp_mux_sink_event (GstPad * pad, GstEvent * event)
|
||||||
GstRTPMuxPadPrivate *padpriv;
|
GstRTPMuxPadPrivate *padpriv;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (mux);
|
GST_OBJECT_LOCK (mux);
|
||||||
|
mux->last_stop = GST_CLOCK_TIME_NONE;
|
||||||
mux->segment_pending = TRUE;
|
mux->segment_pending = TRUE;
|
||||||
padpriv = gst_pad_get_element_private (pad);
|
padpriv = gst_pad_get_element_private (pad);
|
||||||
if (padpriv)
|
if (padpriv)
|
||||||
|
@ -801,6 +845,8 @@ gst_rtp_mux_ready_to_paused (GstRTPMux * rtp_mux)
|
||||||
else
|
else
|
||||||
rtp_mux->ts_base = rtp_mux->ts_offset;
|
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_DEBUG_OBJECT (rtp_mux, "set clock-base to %u", rtp_mux->ts_base);
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (rtp_mux);
|
GST_OBJECT_UNLOCK (rtp_mux);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
#define GST_TYPE_RTP_MUX (gst_rtp_mux_get_type())
|
#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(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_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(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))
|
#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;
|
guint current_ssrc;
|
||||||
|
|
||||||
gboolean segment_pending;
|
gboolean segment_pending;
|
||||||
|
|
||||||
|
GstClockTime last_stop;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstRTPMuxClass
|
struct _GstRTPMuxClass
|
||||||
|
@ -82,6 +84,8 @@ struct _GstRTPMuxClass
|
||||||
|
|
||||||
gboolean (*accept_buffer_locked) (GstRTPMux *rtp_mux,
|
gboolean (*accept_buffer_locked) (GstRTPMux *rtp_mux,
|
||||||
GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer);
|
GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer);
|
||||||
|
|
||||||
|
gboolean (*src_event) (GstRTPMux *rtp_mux, GstEvent *event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue