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);
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
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)
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
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",
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)) {
}
}
gst_iterator_free (iter);
- gst_object_unref (rtp_mux);
gst_event_unref (event);
return result;
object->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
object->segment_pending = TRUE;
+ object->last_stop = GST_CLOCK_TIME_NONE;
}
static void
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);
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)
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)
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);
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))
guint current_ssrc;
gboolean segment_pending;
+
+ GstClockTime last_stop;
};
struct _GstRTPMuxClass
gboolean (*accept_buffer_locked) (GstRTPMux *rtp_mux,
GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer);
+
+ gboolean (*src_event) (GstRTPMux *rtp_mux, GstEvent *event);
};