GST_STATIC_CAPS ("application/x-rtp"));
static GstPad *gst_rtp_dtmf_mux_request_new_pad (GstElement * element,
- GstPadTemplate * templ, const gchar * name);
+ GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static GstStateChangeReturn gst_rtp_dtmf_mux_change_state (GstElement * element,
GstStateChange transition);
static gboolean gst_rtp_dtmf_mux_accept_buffer_locked (GstRTPMux * rtp_mux,
- GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer);
+ GstRTPMuxPadPrivate * padpriv, GstRTPBuffer * rtpbuffer);
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);
+G_DEFINE_TYPE (GstRTPDTMFMux, gst_rtp_dtmf_mux, GST_TYPE_RTP_MUX);
static void
-gst_rtp_dtmf_mux_init (GstRTPDTMFMux * object, GstRTPDTMFMuxClass * g_class)
+gst_rtp_dtmf_mux_init (GstRTPDTMFMux * mux)
{
}
-static void
-gst_rtp_dtmf_mux_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&priority_sink_factory));
-
- gst_element_class_set_details_simple (element_class, "RTP muxer",
- "Codec/Muxer",
- "mixes RTP DTMF streams into other RTP streams",
- "Zeeshan Ali <first.last@nokia.com>");
-}
static void
gst_rtp_dtmf_mux_class_init (GstRTPDTMFMuxClass * klass)
gstelement_class = (GstElementClass *) klass;
gstrtpmux_class = (GstRTPMuxClass *) klass;
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&priority_sink_factory));
+
+ gst_element_class_set_metadata (gstelement_class, "RTP muxer",
+ "Codec/Muxer",
+ "mixes RTP DTMF streams into other RTP streams",
+ "Zeeshan Ali <first.last@nokia.com>");
+
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_rtp_dtmf_mux_request_new_pad);
gstelement_class->change_state =
static gboolean
gst_rtp_dtmf_mux_accept_buffer_locked (GstRTPMux * rtp_mux,
- GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer)
+ GstRTPMuxPadPrivate * padpriv, GstRTPBuffer * rtpbuffer)
{
GstRTPDTMFMux *mux = GST_RTP_DTMF_MUX (rtp_mux);
GstClockTime running_ts;
- running_ts = GST_BUFFER_TIMESTAMP (buffer);
+ running_ts = GST_BUFFER_PTS (rtpbuffer->buffer);
if (GST_CLOCK_TIME_IS_VALID (running_ts)) {
if (padpriv && padpriv->segment.format == GST_FORMAT_TIME)
running_ts = gst_segment_to_running_time (&padpriv->segment,
- GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buffer));
+ GST_FORMAT_TIME, GST_BUFFER_PTS (rtpbuffer->buffer));
if (padpriv && padpriv->priority) {
- if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
+ if (GST_BUFFER_PTS_IS_VALID (rtpbuffer->buffer)) {
if (GST_CLOCK_TIME_IS_VALID (mux->last_priority_end))
mux->last_priority_end =
- MAX (running_ts + GST_BUFFER_DURATION (buffer),
+ MAX (running_ts + GST_BUFFER_DURATION (rtpbuffer->buffer),
mux->last_priority_end);
else
- mux->last_priority_end = running_ts + GST_BUFFER_DURATION (buffer);
+ mux->last_priority_end = running_ts +
+ GST_BUFFER_DURATION (rtpbuffer->buffer);
GST_LOG_OBJECT (mux, "Got buffer %p on priority pad, "
- " blocking regular pads until %" GST_TIME_FORMAT, buffer,
+ " blocking regular pads until %" GST_TIME_FORMAT, rtpbuffer->buffer,
GST_TIME_ARGS (mux->last_priority_end));
} else {
GST_WARNING_OBJECT (mux, "Buffer %p has an invalid duration,"
- " not blocking other pad", buffer);
+ " not blocking other pad", rtpbuffer->buffer);
}
} else {
if (GST_CLOCK_TIME_IS_VALID (mux->last_priority_end) &&
running_ts < mux->last_priority_end) {
GST_LOG_OBJECT (mux, "Dropping buffer %p because running time"
- " %" GST_TIME_FORMAT " < %" GST_TIME_FORMAT, buffer,
+ " %" GST_TIME_FORMAT " < %" GST_TIME_FORMAT, rtpbuffer->buffer,
GST_TIME_ARGS (running_ts), GST_TIME_ARGS (mux->last_priority_end));
return FALSE;
}
}
} else {
GST_LOG_OBJECT (mux, "Buffer %p has an invalid timestamp,"
- " letting through", buffer);
+ " letting through", rtpbuffer->buffer);
}
return TRUE;
static GstPad *
gst_rtp_dtmf_mux_request_new_pad (GstElement * element, GstPadTemplate * templ,
- const gchar * name)
+ const gchar * name, const GstCaps * caps)
{
GstPad *pad;
- pad = GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, request_new_pad,
- (element, templ, name), NULL);
+ pad =
+ GST_ELEMENT_CLASS (gst_rtp_dtmf_mux_parent_class)->request_new_pad
+ (element, templ, name, caps);
if (pad) {
GstRTPMuxPadPrivate *padpriv;
}
}
- return GST_RTP_MUX_CLASS (parent_class)->src_event (rtp_mux, event);
+ return GST_RTP_MUX_CLASS (gst_rtp_dtmf_mux_parent_class)->src_event (rtp_mux,
+ event);
}
break;
}
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ ret =
+ GST_ELEMENT_CLASS (gst_rtp_dtmf_mux_parent_class)->change_state (element,
+ transition);
return ret;
}
);
static GstPad *gst_rtp_mux_request_new_pad (GstElement * element,
- GstPadTemplate * templ, const gchar * name);
+ GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void gst_rtp_mux_release_pad (GstElement * element, GstPad * pad);
-static GstFlowReturn gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer);
-static GstFlowReturn gst_rtp_mux_chain_list (GstPad * pad,
+static GstFlowReturn gst_rtp_mux_chain (GstPad * pad, GstObject * parent,
+ GstBuffer * buffer);
+static GstFlowReturn gst_rtp_mux_chain_list (GstPad * pad, GstObject * parent,
GstBufferList * bufferlist);
-static gboolean gst_rtp_mux_setcaps (GstPad * pad, GstCaps * caps);
-static GstCaps *gst_rtp_mux_getcaps (GstPad * pad);
-static gboolean gst_rtp_mux_sink_event (GstPad * pad, GstEvent * event);
+static gboolean gst_rtp_mux_setcaps (GstPad * pad, GstRTPMux * rtp_mux,
+ GstCaps * caps);
+static gboolean gst_rtp_mux_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
+static gboolean gst_rtp_mux_sink_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
static GstStateChangeReturn gst_rtp_mux_change_state (GstElement *
element, GstStateChange transition);
static gboolean gst_rtp_mux_src_event_real (GstRTPMux * rtp_mux,
GstEvent * event);
-GST_BOILERPLATE (GstRTPMux, gst_rtp_mux, GstElement, GST_TYPE_ELEMENT);
+G_DEFINE_TYPE (GstRTPMux, gst_rtp_mux, GST_TYPE_ELEMENT);
-static void
-gst_rtp_mux_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_factory));
-
- gst_element_class_set_details_simple (element_class, "RTP muxer",
- "Codec/Muxer",
- "multiplex N rtp streams into one", "Zeeshan Ali <first.last@nokia.com>");
-}
static void
gst_rtp_mux_class_init (GstRTPMuxClass * klass)
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&src_factory));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&sink_factory));
+
+ gst_element_class_set_metadata (gstelement_class, "RTP muxer",
+ "Codec/Muxer",
+ "multiplex N rtp streams into one", "Zeeshan Ali <first.last@nokia.com>");
+
gobject_class->get_property = gst_rtp_mux_get_property;
gobject_class->set_property = gst_rtp_mux_set_property;
gobject_class->dispose = gst_rtp_mux_dispose;
}
}
- G_OBJECT_CLASS (parent_class)->dispose (object);
+ G_OBJECT_CLASS (gst_rtp_mux_parent_class)->dispose (object);
}
static gboolean
-gst_rtp_mux_src_event (GstPad * pad, GstEvent * event)
+gst_rtp_mux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
- GstRTPMux *rtp_mux;
+ GstRTPMux *rtp_mux = GST_RTP_MUX (parent);
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;
}
gst_rtp_mux_src_event_real (GstRTPMux * rtp_mux, GstEvent * event)
{
GstIterator *iter;
- GstPad *sinkpad;
gboolean result = FALSE;
gboolean done = FALSE;
iter = gst_element_iterate_sink_pads (GST_ELEMENT (rtp_mux));
while (!done) {
- switch (gst_iterator_next (iter, (gpointer) & sinkpad)) {
+ GValue item = { 0, };
+
+ switch (gst_iterator_next (iter, &item)) {
case GST_ITERATOR_OK:
gst_event_ref (event);
- result |= gst_pad_push_event (sinkpad, event);
- gst_object_unref (sinkpad);
+ result |= gst_pad_push_event (g_value_get_object (&item), event);
break;
case GST_ITERATOR_RESYNC:
gst_iterator_resync (iter);
}
static void
-gst_rtp_mux_init (GstRTPMux * object, GstRTPMuxClass * g_class)
+gst_rtp_mux_init (GstRTPMux * rtp_mux)
{
- GstElementClass *klass = GST_ELEMENT_GET_CLASS (object);
+ GstElementClass *klass = GST_ELEMENT_GET_CLASS (rtp_mux);
+ GstSegment segment;
- object->srcpad =
+ rtp_mux->srcpad =
gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
"src"), "src");
- gst_pad_set_event_function (object->srcpad,
+ gst_pad_set_event_function (rtp_mux->srcpad,
GST_DEBUG_FUNCPTR (gst_rtp_mux_src_event));
- gst_element_add_pad (GST_ELEMENT (object), object->srcpad);
+ gst_element_add_pad (GST_ELEMENT (rtp_mux), rtp_mux->srcpad);
+
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ gst_pad_push_event (rtp_mux->srcpad, gst_event_new_segment (&segment));
- object->ssrc = DEFAULT_SSRC;
- object->ts_offset = DEFAULT_TIMESTAMP_OFFSET;
- object->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
+ rtp_mux->ssrc = DEFAULT_SSRC;
+ rtp_mux->ts_offset = DEFAULT_TIMESTAMP_OFFSET;
+ rtp_mux->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
- object->segment_pending = TRUE;
- object->last_stop = GST_CLOCK_TIME_NONE;
+ rtp_mux->last_stop = GST_CLOCK_TIME_NONE;
}
static void
GstRTPMuxPadPrivate *padpriv = g_slice_new0 (GstRTPMuxPadPrivate);
/* setup some pad functions */
- gst_pad_set_setcaps_function (sinkpad, gst_rtp_mux_setcaps);
- gst_pad_set_getcaps_function (sinkpad, gst_rtp_mux_getcaps);
gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_rtp_mux_chain));
gst_pad_set_chain_list_function (sinkpad,
GST_DEBUG_FUNCPTR (gst_rtp_mux_chain_list));
gst_pad_set_event_function (sinkpad,
GST_DEBUG_FUNCPTR (gst_rtp_mux_sink_event));
+ gst_pad_set_query_function (sinkpad,
+ GST_DEBUG_FUNCPTR (gst_rtp_mux_sink_query));
- gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED);
+ gst_segment_init (&padpriv->segment, GST_FORMAT_TIME);
gst_pad_set_element_private (sinkpad, padpriv);
static GstPad *
gst_rtp_mux_request_new_pad (GstElement * element,
- GstPadTemplate * templ, const gchar * req_name)
+ GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
GstRTPMux *rtp_mux;
GstPad *newpad;
/* Put our own clock-base on the buffer */
static void
gst_rtp_mux_readjust_rtp_timestamp_locked (GstRTPMux * rtp_mux,
- GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer)
+ GstRTPMuxPadPrivate * padpriv, GstRTPBuffer * rtpbuffer)
{
guint32 ts;
guint32 sink_ts_base = 0;
if (padpriv && padpriv->have_clock_base)
sink_ts_base = padpriv->clock_base;
- ts = gst_rtp_buffer_get_timestamp (buffer) - sink_ts_base + rtp_mux->ts_base;
+ ts = gst_rtp_buffer_get_timestamp (rtpbuffer) - sink_ts_base +
+ rtp_mux->ts_base;
GST_LOG_OBJECT (rtp_mux, "Re-adjusting RTP ts %u to %u",
- gst_rtp_buffer_get_timestamp (buffer), ts);
- gst_rtp_buffer_set_timestamp (buffer, ts);
+ gst_rtp_buffer_get_timestamp (rtpbuffer), ts);
+ gst_rtp_buffer_set_timestamp (rtpbuffer, ts);
}
static gboolean
process_buffer_locked (GstRTPMux * rtp_mux, GstRTPMuxPadPrivate * padpriv,
- GstBuffer * buffer)
+ GstRTPBuffer * rtpbuffer)
{
GstRTPMuxClass *klass = GST_RTP_MUX_GET_CLASS (rtp_mux);
if (klass->accept_buffer_locked)
- if (!klass->accept_buffer_locked (rtp_mux, padpriv, buffer))
+ if (!klass->accept_buffer_locked (rtp_mux, padpriv, rtpbuffer))
return FALSE;
rtp_mux->seqnum++;
- gst_rtp_buffer_set_seq (buffer, rtp_mux->seqnum);
+ gst_rtp_buffer_set_seq (rtpbuffer, rtp_mux->seqnum);
- gst_rtp_buffer_set_ssrc (buffer, rtp_mux->current_ssrc);
- gst_rtp_mux_readjust_rtp_timestamp_locked (rtp_mux, padpriv, buffer);
+ gst_rtp_buffer_set_ssrc (rtpbuffer, rtp_mux->current_ssrc);
+ gst_rtp_mux_readjust_rtp_timestamp_locked (rtp_mux, padpriv, rtpbuffer);
GST_LOG_OBJECT (rtp_mux, "Pushing packet size %d, seq=%d, ts=%u",
- GST_BUFFER_SIZE (buffer), rtp_mux->seqnum,
- gst_rtp_buffer_get_timestamp (buffer));
+ rtpbuffer->size, rtp_mux->seqnum,
+ gst_rtp_buffer_get_timestamp (rtpbuffer));
if (padpriv) {
- gst_buffer_set_caps (buffer, padpriv->out_caps);
if (padpriv->segment.format == GST_FORMAT_TIME)
- GST_BUFFER_TIMESTAMP (buffer) =
+ GST_BUFFER_PTS (rtpbuffer->buffer) =
gst_segment_to_running_time (&padpriv->segment, GST_FORMAT_TIME,
- GST_BUFFER_TIMESTAMP (buffer));
+ GST_BUFFER_PTS (rtpbuffer->buffer));
}
return TRUE;
}
+struct BufferListData
+{
+ GstRTPMux *rtp_mux;
+ GstRTPMuxPadPrivate *padpriv;
+ gboolean drop;
+};
+
+static gboolean
+process_list_item (GstBuffer ** buffer, guint idx, gpointer user_data)
+{
+ struct BufferListData *bd = user_data;
+ GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
+
+ *buffer = gst_buffer_make_writable (*buffer);
+
+ gst_rtp_buffer_map (*buffer, GST_MAP_READWRITE, &rtpbuffer);
+
+ bd->drop = !process_buffer_locked (bd->rtp_mux, bd->padpriv, &rtpbuffer);
+
+ gst_rtp_buffer_unmap (&rtpbuffer);
+
+ if (bd->drop)
+ return FALSE;
+
+ if (GST_BUFFER_DURATION_IS_VALID (*buffer) &&
+ GST_BUFFER_TIMESTAMP_IS_VALID (*buffer))
+ bd->rtp_mux->last_stop = GST_BUFFER_TIMESTAMP (*buffer) +
+ GST_BUFFER_DURATION (*buffer);
+ else
+ bd->rtp_mux->last_stop = GST_CLOCK_TIME_NONE;
+
+ return TRUE;
+}
+
static GstFlowReturn
-gst_rtp_mux_chain_list (GstPad * pad, GstBufferList * bufferlist)
+gst_rtp_mux_chain_list (GstPad * pad, GstObject * parent,
+ GstBufferList * bufferlist)
{
GstRTPMux *rtp_mux;
GstFlowReturn ret;
- GstBufferListIterator *it;
GstRTPMuxPadPrivate *padpriv;
- GstEvent *newseg_event = NULL;
gboolean drop = TRUE;
+ struct BufferListData bd;
- rtp_mux = GST_RTP_MUX (gst_pad_get_parent (pad));
-
- if (!gst_rtp_buffer_list_validate (bufferlist)) {
- GST_ERROR_OBJECT (rtp_mux, "Invalid RTP buffer");
- gst_object_unref (rtp_mux);
- return GST_FLOW_ERROR;
- }
+ rtp_mux = GST_RTP_MUX (parent);
GST_OBJECT_LOCK (rtp_mux);
goto out;
}
- bufferlist = gst_buffer_list_make_writable (bufferlist);
- it = gst_buffer_list_iterate (bufferlist);
- while (gst_buffer_list_iterator_next_group (it)) {
- GstBuffer *rtpbuf;
-
- rtpbuf = gst_buffer_list_iterator_next (it);
- rtpbuf = gst_buffer_make_writable (rtpbuf);
-
- drop = !process_buffer_locked (rtp_mux, padpriv, rtpbuf);
-
- if (drop)
- 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);
-
- 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);
+ bd.rtp_mux = rtp_mux;
+ bd.padpriv = padpriv;
+ bd.drop = FALSE;
- rtp_mux->segment_pending = FALSE;
- }
+ bufferlist = gst_buffer_list_make_writable (bufferlist);
+ gst_buffer_list_foreach (bufferlist, process_list_item, &bd);
GST_OBJECT_UNLOCK (rtp_mux);
- if (newseg_event)
- gst_pad_push_event (rtp_mux->srcpad, newseg_event);
-
if (drop) {
gst_buffer_list_unref (bufferlist);
ret = GST_FLOW_OK;
out:
- gst_object_unref (rtp_mux);
-
return ret;
}
static GstFlowReturn
-gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer)
+gst_rtp_mux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
GstRTPMux *rtp_mux;
GstFlowReturn ret;
GstRTPMuxPadPrivate *padpriv;
GstEvent *newseg_event = NULL;
gboolean drop;
+ GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
rtp_mux = GST_RTP_MUX (GST_OBJECT_PARENT (pad));
buffer = gst_buffer_make_writable (buffer);
- drop = !process_buffer_locked (rtp_mux, padpriv, buffer);
+ gst_rtp_buffer_map (buffer, GST_MAP_READWRITE, &rtpbuffer);
- 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;
- }
+ drop = !process_buffer_locked (rtp_mux, padpriv, &rtpbuffer);
+ gst_rtp_buffer_unmap (&rtpbuffer);
+
+ if (!drop) {
if (GST_BUFFER_DURATION_IS_VALID (buffer) &&
GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
rtp_mux->last_stop = GST_BUFFER_TIMESTAMP (buffer) +
}
static gboolean
-gst_rtp_mux_setcaps (GstPad * pad, GstCaps * caps)
+gst_rtp_mux_setcaps (GstPad * pad, GstRTPMux * rtp_mux, GstCaps * caps)
{
- GstRTPMux *rtp_mux;
GstStructure *structure;
gboolean ret = FALSE;
GstRTPMuxPadPrivate *padpriv;
- rtp_mux = GST_RTP_MUX (gst_pad_get_parent (pad));
-
structure = gst_caps_get_structure (caps, 0);
if (!structure)
- goto out;
+ return FALSE;
GST_OBJECT_LOCK (rtp_mux);
padpriv = gst_pad_get_element_private (pad);
}
gst_caps_unref (caps);
-out:
- gst_object_unref (rtp_mux);
-
return ret;
}
}
static gboolean
-same_clock_rate_fold (gpointer item, GValue * ret, gpointer user_data)
+same_clock_rate_fold (const GValue * item, GValue * ret, gpointer user_data)
{
GstPad *mypad = user_data;
- GstPad *pad = item;
+ GstPad *pad = g_value_get_object (item);
GstCaps *peercaps;
- GstCaps *othercaps;
const GstCaps *accumcaps;
GstCaps *intersect;
if (pad == mypad) {
- gst_object_unref (pad);
return TRUE;
}
- peercaps = gst_pad_peer_get_caps (pad);
+ accumcaps = gst_value_get_caps (ret);
+ peercaps = gst_pad_peer_query_caps (pad, (GstCaps *) accumcaps);
if (!peercaps) {
- gst_object_unref (pad);
+ g_warning ("no peercaps");
return TRUE;
}
+ peercaps = gst_caps_make_writable (peercaps);
+ clear_caps (peercaps, TRUE);
- othercaps = gst_caps_intersect (peercaps,
- gst_pad_get_pad_template_caps (pad));
- gst_caps_unref (peercaps);
-
- accumcaps = gst_value_get_caps (ret);
-
- clear_caps (othercaps, TRUE);
-
- intersect = gst_caps_intersect (accumcaps, othercaps);
+ intersect = gst_caps_intersect (accumcaps, peercaps);
g_value_take_boxed (ret, intersect);
-
- gst_caps_unref (othercaps);
- gst_object_unref (pad);
+ gst_caps_unref (peercaps);
return !gst_caps_is_empty (intersect);
}
static GstCaps *
-gst_rtp_mux_getcaps (GstPad * pad)
+gst_rtp_mux_getcaps (GstPad * pad, GstRTPMux * mux, GstCaps * filter)
{
- GstRTPMux *mux = GST_RTP_MUX (gst_pad_get_parent (pad));
GstCaps *caps = NULL;
GstIterator *iter = NULL;
GValue v = { 0 };
GstIteratorResult res;
- GstCaps *peercaps = gst_pad_peer_get_caps (mux->srcpad);
+ GstCaps *peercaps;
GstCaps *othercaps = NULL;
+ GstCaps *filtered_caps;
+
+ peercaps = gst_pad_peer_query_caps (mux->srcpad, filter);
if (peercaps) {
othercaps = gst_caps_intersect (peercaps,
othercaps = gst_caps_copy (gst_pad_get_pad_template_caps (mux->srcpad));
}
- clear_caps (othercaps, FALSE);
+ if (filter) {
+ filtered_caps = gst_caps_intersect (othercaps, filter);
+ gst_caps_unref (othercaps);
+ } else {
+ filtered_caps = othercaps;
+ }
+
+ filtered_caps = gst_caps_make_writable (filtered_caps);
+ clear_caps (filtered_caps, FALSE);
g_value_init (&v, GST_TYPE_CAPS);
iter = gst_element_iterate_sink_pads (GST_ELEMENT (mux));
do {
- gst_value_set_caps (&v, othercaps);
+ gst_value_set_caps (&v, filtered_caps);
res = gst_iterator_fold (iter, same_clock_rate_fold, &v, pad);
} while (res == GST_ITERATOR_RESYNC);
gst_iterator_free (iter);
caps = gst_caps_new_empty ();
}
- if (othercaps)
- gst_caps_unref (othercaps);
- gst_object_unref (mux);
+ gst_caps_unref (filtered_caps);
return caps;
}
+static gboolean
+gst_rtp_mux_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+ GstRTPMux *mux = GST_RTP_MUX (parent);
+ gboolean res = FALSE;
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CAPS:
+ {
+ GstCaps *filter, *caps;
+
+ gst_query_parse_caps (query, &filter);
+ caps = gst_rtp_mux_getcaps (pad, mux, filter);
+ gst_query_set_caps_result (query, caps);
+ gst_caps_unref (caps);
+ res = TRUE;
+ break;
+ }
+ default:
+ res = gst_pad_query_default (pad, parent, query);
+ break;
+ }
+
+ return res;
+
+
+}
+
static void
gst_rtp_mux_get_property (GObject * object,
}
static gboolean
-gst_rtp_mux_sink_event (GstPad * pad, GstEvent * event)
+gst_rtp_mux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstRTPMux *mux;
gboolean ret = FALSE;
gboolean forward = TRUE;
- mux = GST_RTP_MUX (gst_pad_get_parent (pad));
+ mux = GST_RTP_MUX (parent);
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_FLUSH_STOP:
+ case GST_EVENT_CAPS:
{
- GstRTPMuxPadPrivate *padpriv;
+ GstCaps *caps;
+ gst_event_parse_caps (event, &caps);
+ ret = gst_rtp_mux_setcaps (pad, mux, caps);
+ forward = FALSE;
+ break;
+ }
+ case GST_EVENT_FLUSH_STOP:
+ {
GST_OBJECT_LOCK (mux);
mux->last_stop = GST_CLOCK_TIME_NONE;
- mux->segment_pending = TRUE;
- padpriv = gst_pad_get_element_private (pad);
- if (padpriv)
- gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED);
GST_OBJECT_UNLOCK (mux);
- }
break;
- case GST_EVENT_NEWSEGMENT:
+ }
+ case GST_EVENT_SEGMENT:
{
- gboolean update;
- gdouble rate, applied_rate;
- GstFormat format;
- gint64 start, stop, position;
GstRTPMuxPadPrivate *padpriv;
- gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
- &format, &start, &stop, &position);
-
GST_OBJECT_LOCK (mux);
padpriv = gst_pad_get_element_private (pad);
if (padpriv) {
- if (format == GST_FORMAT_TIME)
- gst_segment_set_newsegment_full (&padpriv->segment, update,
- rate, applied_rate, format, start, stop, position);
- else
- gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED);
+ gst_event_copy_segment (event, &padpriv->segment);
}
GST_OBJECT_UNLOCK (mux);
gst_event_unref (event);
if (forward)
ret = gst_pad_push_event (mux->srcpad, event);
- gst_object_unref (mux);
return ret;
}
-
-static void
-clear_segment (gpointer data, gpointer user_data)
-{
- GstPad *pad = data;
- GstRTPMux *mux = user_data;
- GstRTPMuxPadPrivate *padpriv;
-
- GST_OBJECT_LOCK (mux);
- padpriv = gst_pad_get_element_private (pad);
- if (padpriv)
- gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED);
- GST_OBJECT_UNLOCK (mux);
-
- gst_object_unref (pad);
-}
-
-
static void
gst_rtp_mux_ready_to_paused (GstRTPMux * rtp_mux)
{
- GstIterator *iter;
-
- iter = gst_element_iterate_sink_pads (GST_ELEMENT (rtp_mux));
- while (gst_iterator_foreach (iter, clear_segment, rtp_mux) ==
- GST_ITERATOR_RESYNC);
- gst_iterator_free (iter);
GST_OBJECT_LOCK (rtp_mux);
- rtp_mux->segment_pending = TRUE;
if (rtp_mux->ssrc == -1)
rtp_mux->current_ssrc = g_random_int ();
break;
}
- return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ return GST_ELEMENT_CLASS (gst_rtp_mux_parent_class)->change_state (element,
+ transition);
}
gboolean
typedef void (*check_cb) (GstPad * pad, int i);
-static GstCaps *
-getcaps_func (GstPad * pad)
-{
- GstCaps **caps = g_object_get_data (G_OBJECT (pad), "caps");
-
- fail_unless (caps != NULL && *caps != NULL);
-
- return gst_caps_ref (*caps);
-}
-
static gboolean
-setcaps_func (GstPad * pad, GstCaps * caps)
+query_func (GstPad * pad, GstObject * noparent, GstQuery * query)
{
- GstCaps **caps2 = g_object_get_data (G_OBJECT (pad), "caps");
-
- fail_unless (caps2 != NULL && *caps2 != NULL);
-
- fail_unless (gst_caps_is_equal (caps, *caps2));
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CAPS:
+ {
+ GstCaps **caps = g_object_get_data (G_OBJECT (pad), "caps");
+
+ fail_unless (caps != NULL && *caps != NULL);
+ gst_query_set_caps_result (query, *caps);
+ break;
+ }
+ default:
+ break;
+ }
return TRUE;
}
static gboolean
-event_func (GstPad * pad, GstEvent * event)
+event_func (GstPad * pad, GstObject * noparent, GstEvent * event)
{
- gst_event_unref (event);
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+ GstCaps **caps2 = g_object_get_data (G_OBJECT (pad), "caps");
+
+ gst_event_parse_caps (event, &caps);
+ fail_unless (caps2 != NULL && *caps2 != NULL);
+ fail_unless (gst_caps_is_equal (caps, *caps2));
+ break;
+ }
+ default:
+ gst_event_unref (event);
+ break;
+ }
return TRUE;
}
GstCaps *src2caps = NULL;
GstCaps *sinkcaps = NULL;
GstCaps *caps;
- GstEvent *newsegment;
+ GstSegment segment;
int i;
rtpmux = gst_check_setup_element (elem_name);
src2 = gst_pad_new_from_static_template (&srctemplate, "src");
fail_unless (gst_pad_link (src1, reqpad1) == GST_PAD_LINK_OK);
fail_unless (gst_pad_link (src2, reqpad2) == GST_PAD_LINK_OK);
- gst_pad_set_getcaps_function (src1, getcaps_func);
- gst_pad_set_getcaps_function (src2, getcaps_func);
- gst_pad_set_getcaps_function (sink, getcaps_func);
- gst_pad_set_setcaps_function (sink, setcaps_func);
+ gst_pad_set_query_function (src1, query_func);
+ gst_pad_set_query_function (src2, query_func);
+ gst_pad_set_query_function (sink, query_func);
gst_pad_set_event_function (sink, event_func);
g_object_set_data (G_OBJECT (src1), "caps", &src1caps);
g_object_set_data (G_OBJECT (src2), "caps", &src2caps);
sinkcaps = gst_caps_new_simple ("application/x-rtp",
"clock-rate", G_TYPE_INT, 3, "ssrc", G_TYPE_UINT, 13, NULL);
- caps = gst_pad_peer_get_caps (src1);
+ caps = gst_pad_peer_query_caps (src1, NULL);
fail_unless (gst_caps_is_empty (caps));
gst_caps_unref (caps);
gst_caps_set_simple (src2caps, "clock-rate", G_TYPE_INT, 3, NULL);
- caps = gst_pad_peer_get_caps (src1);
+ caps = gst_pad_peer_query_caps (src1, NULL);
fail_unless (gst_caps_is_equal (caps, sinkcaps));
gst_caps_unref (caps);
"ssrc", G_TYPE_UINT, 66, NULL);
fail_unless (gst_pad_set_caps (src1, caps));
- newsegment = gst_event_new_new_segment (FALSE, 1, GST_FORMAT_TIME, 100000,
- -1, 0);
- fail_unless (gst_pad_push_event (src1, newsegment));
- newsegment = gst_event_new_new_segment (FALSE, 1, GST_FORMAT_TIME, 0, -1, 0);
- fail_unless (gst_pad_push_event (src2, newsegment));
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ segment.start = 100000;
+ fail_unless (gst_pad_push_event (src1, gst_event_new_segment (&segment)));
+ segment.start = 0;
+ fail_unless (gst_pad_push_event (src2, gst_event_new_segment (&segment)));
+
for (i = 0; i < count; i++) {
+ GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
+
inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
- GST_BUFFER_TIMESTAMP (inbuf) = i * 1000 + 100000;
+ GST_BUFFER_PTS (inbuf) = i * 1000 + 100000;
GST_BUFFER_DURATION (inbuf) = 1000;
- gst_buffer_set_caps (inbuf, caps);
- gst_rtp_buffer_set_version (inbuf, 2);
- gst_rtp_buffer_set_payload_type (inbuf, 98);
- gst_rtp_buffer_set_ssrc (inbuf, 44);
- gst_rtp_buffer_set_timestamp (inbuf, 200 + i);
- gst_rtp_buffer_set_seq (inbuf, 2000 + i);
+
+ gst_rtp_buffer_map (inbuf, GST_MAP_WRITE, &rtpbuffer);
+
+ gst_rtp_buffer_set_version (&rtpbuffer, 2);
+ gst_rtp_buffer_set_payload_type (&rtpbuffer, 98);
+ gst_rtp_buffer_set_ssrc (&rtpbuffer, 44);
+ gst_rtp_buffer_set_timestamp (&rtpbuffer, 200 + i);
+ gst_rtp_buffer_set_seq (&rtpbuffer, 2000 + i);
+ gst_rtp_buffer_unmap (&rtpbuffer);
fail_unless (gst_pad_push (src1, inbuf) == GST_FLOW_OK);
if (buffers)
- fail_unless (GST_BUFFER_TIMESTAMP (buffers->data) == i * 1000, "%lld",
- GST_BUFFER_TIMESTAMP (buffers->data));
+ fail_unless (GST_BUFFER_PTS (buffers->data) == i * 1000, "%lld",
+ GST_BUFFER_PTS (buffers->data));
cb (src2, i);
static void
basic_check_cb (GstPad * pad, int i)
{
+ GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
fail_unless (buffers && g_list_length (buffers) == 1);
- fail_unless (gst_rtp_buffer_get_ssrc (buffers->data) == 55);
- fail_unless (gst_rtp_buffer_get_timestamp (buffers->data) ==
+
+ gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
+ fail_unless (gst_rtp_buffer_get_ssrc (&rtpbuffer) == 55);
+ fail_unless (gst_rtp_buffer_get_timestamp (&rtpbuffer) ==
200 - 57 + 1000 + i);
- fail_unless (gst_rtp_buffer_get_seq (buffers->data) == 100 + 1 + i);
+ fail_unless (gst_rtp_buffer_get_seq (&rtpbuffer) == 100 + 1 + i);
+ gst_rtp_buffer_unmap (&rtpbuffer);
}
if (i % 2) {
fail_unless (buffers == NULL);
} else {
+ GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
+
fail_unless (buffers && g_list_length (buffers) == 1);
- fail_unless (gst_rtp_buffer_get_ssrc (buffers->data) == 55);
- fail_unless (gst_rtp_buffer_get_timestamp (buffers->data) ==
+ gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
+ fail_unless (gst_rtp_buffer_get_ssrc (&rtpbuffer) == 55);
+ fail_unless (gst_rtp_buffer_get_timestamp (&rtpbuffer) ==
200 - 57 + 1000 + i);
- fail_unless (gst_rtp_buffer_get_seq (buffers->data) == 100 + 1 + i);
+ fail_unless (gst_rtp_buffer_get_seq (&rtpbuffer) == 100 + 1 + i);
+ gst_rtp_buffer_unmap (&rtpbuffer);
inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
- GST_BUFFER_TIMESTAMP (inbuf) = i * 1000 + 500;
+ GST_BUFFER_PTS (inbuf) = i * 1000 + 500;
GST_BUFFER_DURATION (inbuf) = 1000;
- gst_rtp_buffer_set_version (inbuf, 2);
- gst_rtp_buffer_set_payload_type (inbuf, 98);
- gst_rtp_buffer_set_ssrc (inbuf, 44);
- gst_rtp_buffer_set_timestamp (inbuf, 200 + i);
- gst_rtp_buffer_set_seq (inbuf, 2000 + i);
+ gst_rtp_buffer_map (inbuf, GST_MAP_WRITE, &rtpbuffer);
+ gst_rtp_buffer_set_version (&rtpbuffer, 2);
+ gst_rtp_buffer_set_payload_type (&rtpbuffer, 98);
+ gst_rtp_buffer_set_ssrc (&rtpbuffer, 44);
+ gst_rtp_buffer_set_timestamp (&rtpbuffer, 200 + i);
+ gst_rtp_buffer_set_seq (&rtpbuffer, 2000 + i);
+ gst_rtp_buffer_unmap (&rtpbuffer);
fail_unless (gst_pad_push (pad, inbuf) == GST_FLOW_OK);