From ef02634dc642d3d415ff52f9a8bc2f74c8c8a4e7 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 6 Jul 2011 10:11:52 +0200 Subject: [PATCH] rtpmanager: port to 0.11 * use G_DEFINE_TYPE * adjust to new GstBuffer and corresponding rtp and rtcp buffer interfaces * misc caps and segment handling changes FIXME: also relies on being able to pass caps along with a buffer, which has no evident equivalent yet, so that either needs one, or still needs quite some code path modification to drag along caps. --- gst/rtpmanager/gstrtpptdemux.c | 48 ++++----- gst/rtpmanager/gstrtpsession.c | 173 +++++++++++++++---------------- gst/rtpmanager/gstrtpssrcdemux.c | 82 ++++++++------- gst/rtpmanager/rtpjitterbuffer.c | 24 ++++- gst/rtpmanager/rtpsession.c | 106 +++++++++++++------ gst/rtpmanager/rtpsource.c | 79 +++++++++----- 6 files changed, 298 insertions(+), 214 deletions(-) diff --git a/gst/rtpmanager/gstrtpptdemux.c b/gst/rtpmanager/gstrtpptdemux.c index 3c0004dbbc..ce777730de 100644 --- a/gst/rtpmanager/gstrtpptdemux.c +++ b/gst/rtpmanager/gstrtpptdemux.c @@ -117,7 +117,8 @@ enum LAST_SIGNAL }; -GST_BOILERPLATE (GstRtpPtDemux, gst_rtp_pt_demux, GstElement, GST_TYPE_ELEMENT); +#define gst_rtp_pt_demux_parent_class parent_class +G_DEFINE_TYPE (GstRtpPtDemux, gst_rtp_pt_demux, GST_TYPE_ELEMENT); static void gst_rtp_pt_demux_finalize (GObject * object); @@ -137,22 +138,6 @@ static gboolean gst_rtp_pt_demux_src_event (GstPad * pad, GstEvent * event); static guint gst_rtp_pt_demux_signals[LAST_SIGNAL] = { 0 }; -static void -gst_rtp_pt_demux_base_init (gpointer g_class) -{ - GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_pt_demux_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_pt_demux_src_template)); - - gst_element_class_set_details_simple (gstelement_klass, "RTP Demux", - "Demux/Network/RTP", - "Parses codec streams transmitted in the same RTP session", - "Kai Vehmanen "); -} - static void gst_rtp_pt_demux_class_init (GstRtpPtDemuxClass * klass) { @@ -222,12 +207,22 @@ gst_rtp_pt_demux_class_init (GstRtpPtDemuxClass * klass) klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_pt_demux_clear_pt_map); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&rtp_pt_demux_sink_template)); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&rtp_pt_demux_src_template)); + + gst_element_class_set_details_simple (gstelement_klass, "RTP Demux", + "Demux/Network/RTP", + "Parses codec streams transmitted in the same RTP session", + "Kai Vehmanen "); + GST_DEBUG_CATEGORY_INIT (gst_rtp_pt_demux_debug, "rtpptdemux", 0, "RTP codec demuxer"); } static void -gst_rtp_pt_demux_init (GstRtpPtDemux * ptdemux, GstRtpPtDemuxClass * g_class) +gst_rtp_pt_demux_init (GstRtpPtDemux * ptdemux) { GstElementClass *klass = GST_ELEMENT_GET_CLASS (ptdemux); @@ -274,9 +269,7 @@ gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt) caps = g_value_dup_boxed (&ret); g_value_unset (&ret); if (caps == NULL) { - caps = GST_PAD_CAPS (rtpdemux->sink); - if (caps) - gst_caps_ref (caps); + caps = gst_pad_get_current_caps (rtpdemux->sink); } GST_DEBUG ("pt %d, got caps %" GST_PTR_FORMAT, pt, caps); @@ -309,13 +302,16 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf) GstPad *srcpad; GstRtpPtDemuxPad *rtpdemuxpad; GstCaps *caps; + GstRTPBuffer rtp; rtpdemux = GST_RTP_PT_DEMUX (GST_OBJECT_PARENT (pad)); if (!gst_rtp_buffer_validate (buf)) goto invalid_buffer; - pt = gst_rtp_buffer_get_payload_type (buf); + gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp); + pt = gst_rtp_buffer_get_payload_type (&rtp); + gst_rtp_buffer_unmap (&rtp); GST_DEBUG_OBJECT (rtpdemux, "received buffer for pt %d", pt); @@ -385,8 +381,6 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf) rtpdemuxpad->newcaps = FALSE; } - gst_buffer_set_caps (buf, GST_PAD_CAPS (srcpad)); - /* push to srcpad */ ret = gst_pad_push (srcpad, buf); @@ -490,11 +484,13 @@ gst_rtp_pt_demux_src_event (GstPad * pad, GstEvent * event) GstRtpPtDemuxPad *dpad = (GstRtpPtDemuxPad *) walk->data; if (dpad->pad == pad) { + GstStructure *ws; + event = GST_EVENT_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (event))); - gst_structure_set (event->structure, - "payload", G_TYPE_UINT, dpad->pt, NULL); + ws = gst_event_writable_structure (event); + gst_structure_set (ws, "payload", G_TYPE_UINT, dpad->pt, NULL); break; } } diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index ebeb3fd9bc..4b112fa643 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -284,9 +284,12 @@ static void gst_rtp_session_get_property (GObject * object, guint prop_id, static GstStateChangeReturn gst_rtp_session_change_state (GstElement * element, GstStateChange transition); static GstPad *gst_rtp_session_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name); + GstPadTemplate * templ, const gchar * name, const GstCaps * caps); static void gst_rtp_session_release_pad (GstElement * element, GstPad * pad); +static gboolean gst_rtp_session_sink_setcaps (GstPad * pad, GstCaps * caps); +static gboolean gst_rtp_session_setcaps_send_rtp (GstPad * pad, GstCaps * caps); + static void gst_rtp_session_clear_pt_map (GstRtpSession * rtpsession); static guint gst_rtp_session_signals[LAST_SIGNAL] = { 0 }; @@ -365,35 +368,8 @@ on_sender_timeout (RTPSession * session, RTPSource * src, GstRtpSession * sess) src->ssrc); } -GST_BOILERPLATE (GstRtpSession, gst_rtp_session, GstElement, GST_TYPE_ELEMENT); - -static void -gst_rtp_session_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - /* sink pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_recv_rtp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_recv_rtcp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_send_rtp_sink_template)); - - /* src pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_recv_rtp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_sync_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_send_rtp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_send_rtcp_src_template)); - - gst_element_class_set_details_simple (element_class, "RTP Session", - "Filter/Network/RTP", - "Implement an RTP session", "Wim Taymans "); -} +#define gst_rtp_session_parent_class parent_class +G_DEFINE_TYPE (GstRtpSession, gst_rtp_session, GST_TYPE_ELEMENT); static void gst_rtp_session_class_init (GstRtpSessionClass * klass) @@ -611,12 +587,34 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass) klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_session_clear_pt_map); + /* sink pads */ + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&rtpsession_recv_rtp_sink_template)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&rtpsession_recv_rtcp_sink_template)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&rtpsession_send_rtp_sink_template)); + + /* src pads */ + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&rtpsession_recv_rtp_src_template)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&rtpsession_sync_src_template)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&rtpsession_send_rtp_src_template)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&rtpsession_send_rtcp_src_template)); + + gst_element_class_set_details_simple (gstelement_class, "RTP Session", + "Filter/Network/RTP", + "Implement an RTP session", "Wim Taymans "); + GST_DEBUG_CATEGORY_INIT (gst_rtp_session_debug, "rtpsession", 0, "RTP Session"); } static void -gst_rtp_session_init (GstRtpSession * rtpsession, GstRtpSessionClass * klass) +gst_rtp_session_init (GstRtpSession * rtpsession) { rtpsession->priv = GST_RTP_SESSION_GET_PRIVATE (rtpsession); rtpsession->priv->lock = g_mutex_new (); @@ -977,7 +975,7 @@ gst_rtp_session_change_state (GstElement * element, GstStateChange transition) break; } - res = parent_class->change_state (element, transition); + res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -1099,12 +1097,10 @@ gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src, GstCaps *caps; /* set rtcp caps on output pad */ - if (!(caps = GST_PAD_CAPS (rtcp_src))) { + if (!(caps = gst_pad_get_current_caps (rtcp_src))) { caps = gst_caps_new_simple ("application/x-rtcp", NULL); gst_pad_set_caps (rtcp_src, caps); - } else - gst_caps_ref (caps); - gst_buffer_set_caps (buffer, caps); + } gst_caps_unref (caps); gst_object_ref (rtcp_src); @@ -1158,12 +1154,10 @@ gst_rtp_session_sync_rtcp (RTPSession * sess, RTPSource * src, GstCaps *caps; /* set rtcp caps on output pad */ - if (!(caps = GST_PAD_CAPS (sync_src))) { + if (!(caps = gst_pad_get_current_caps (sync_src))) { caps = gst_caps_new_simple ("application/x-rtcp", NULL); gst_pad_set_caps (sync_src, caps); - } else - gst_caps_ref (caps); - gst_buffer_set_caps (buffer, caps); + } gst_caps_unref (caps); gst_object_ref (sync_src); @@ -1334,37 +1328,36 @@ gst_rtp_session_event_recv_rtp_sink (GstPad * pad, GstEvent * event) GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CAPS: + { + GstCaps *caps; + + /* process */ + gst_event_parse_caps (event, &caps); + gst_rtp_session_sink_setcaps (pad, caps); + /* and eat */ + gst_event_unref (event); + break; + } case GST_EVENT_FLUSH_STOP: gst_segment_init (&rtpsession->recv_rtp_seg, GST_FORMAT_UNDEFINED); ret = gst_pad_push_event (rtpsession->recv_rtp_src, event); break; - case GST_EVENT_NEWSEGMENT: + case GST_EVENT_SEGMENT: { - gboolean update; - gdouble rate, arate; - GstFormat format; - gint64 start, stop, time; - GstSegment *segment; + GstSegment *segment, in_segment; segment = &rtpsession->recv_rtp_seg; /* the newsegment event is needed to convert the RTP timestamp to * running_time, which is needed to generate a mapping from RTP to NTP * timestamps in SR reports */ - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); + gst_event_copy_segment (event, &in_segment); + GST_DEBUG_OBJECT (rtpsession, "received segment %" GST_SEGMENT_FORMAT, + in_segment); - GST_DEBUG_OBJECT (rtpsession, - "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, " - "format GST_FORMAT_TIME, " - "%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT - ", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT, - update, rate, arate, GST_TIME_ARGS (segment->start), - GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time), - GST_TIME_ARGS (segment->accum)); - - gst_segment_set_newsegment_full (segment, update, rate, - arate, format, start, stop, time); + /* accept upstream */ + gst_segment_copy_into (&in_segment, segment); /* push event forward */ ret = gst_pad_push_event (rtpsession->recv_rtp_src, event); @@ -1475,8 +1468,12 @@ gst_rtp_session_iterate_internal_links (GstPad * pad) GST_RTP_SESSION_UNLOCK (rtpsession); if (otherpad) { - it = gst_iterator_new_single (GST_TYPE_PAD, otherpad, - (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref); + GValue val = { 0, }; + + g_value_init (&val, GST_TYPE_PAD); + g_value_set_object (&val, otherpad); + it = gst_iterator_new_single (GST_TYPE_PAD, &val); + g_value_unset (&val); gst_object_unref (otherpad); } @@ -1664,36 +1661,35 @@ gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstEvent * event) GST_DEBUG_OBJECT (rtpsession, "received event"); switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CAPS: + { + GstCaps *caps; + + /* process */ + gst_event_parse_caps (event, &caps); + gst_rtp_session_setcaps_send_rtp (pad, caps); + /* and eat */ + gst_event_unref (event); + break; + } case GST_EVENT_FLUSH_STOP: gst_segment_init (&rtpsession->send_rtp_seg, GST_FORMAT_UNDEFINED); ret = gst_pad_push_event (rtpsession->send_rtp_src, event); break; - case GST_EVENT_NEWSEGMENT:{ - gboolean update; - gdouble rate, arate; - GstFormat format; - gint64 start, stop, time; - GstSegment *segment; + case GST_EVENT_SEGMENT:{ + GstSegment *segment, in_segment; segment = &rtpsession->send_rtp_seg; /* the newsegment event is needed to convert the RTP timestamp to * running_time, which is needed to generate a mapping from RTP to NTP * timestamps in SR reports */ - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); + gst_event_copy_segment (event, &in_segment); + GST_DEBUG_OBJECT (rtpsession, "received segment %" GST_SEGMENT_FORMAT, + in_segment); - GST_DEBUG_OBJECT (rtpsession, - "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, " - "format GST_FORMAT_TIME, " - "%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT - ", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT, - update, rate, arate, GST_TIME_ARGS (segment->start), - GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time), - GST_TIME_ARGS (segment->accum)); - - gst_segment_set_newsegment_full (segment, update, rate, - arate, format, start, stop, time); + /* accept upstream */ + gst_segment_copy_into (&in_segment, segment); /* push event forward */ ret = gst_pad_push_event (rtpsession->send_rtp_src, event); @@ -1733,7 +1729,7 @@ gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstEvent * event) } static GstCaps * -gst_rtp_session_getcaps_send_rtp (GstPad * pad) +gst_rtp_session_getcaps_send_rtp (GstPad * pad, GstCaps * filter) { GstRtpSession *rtpsession; GstRtpSessionPrivate *priv; @@ -1754,6 +1750,13 @@ gst_rtp_session_getcaps_send_rtp (GstPad * pad) result = gst_caps_new_full (s1, s2, NULL); + if (filter) { + GstCaps *caps = result; + + result = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + } + GST_DEBUG_OBJECT (rtpsession, "getting caps %" GST_PTR_FORMAT, result); gst_object_unref (rtpsession); @@ -1806,7 +1809,7 @@ gst_rtp_session_chain_send_rtp_common (GstPad * pad, gpointer data, /* All groups in an list have the same timestamp. * So, just take it from the first group. */ - buffer = gst_buffer_list_get (GST_BUFFER_LIST_CAST (data), 0, 0); + buffer = gst_buffer_list_get (GST_BUFFER_LIST_CAST (data), 0); if (buffer) timestamp = GST_BUFFER_TIMESTAMP (buffer); else @@ -1872,8 +1875,6 @@ create_recv_rtp_sink (GstRtpSession * rtpsession) gst_rtp_session_chain_recv_rtp); gst_pad_set_event_function (rtpsession->recv_rtp_sink, (GstPadEventFunction) gst_rtp_session_event_recv_rtp_sink); - gst_pad_set_setcaps_function (rtpsession->recv_rtp_sink, - gst_rtp_session_sink_setcaps); gst_pad_set_iterate_internal_links_function (rtpsession->recv_rtp_sink, gst_rtp_session_iterate_internal_links); gst_pad_set_active (rtpsession->recv_rtp_sink, TRUE); @@ -1986,8 +1987,6 @@ create_send_rtp_sink (GstRtpSession * rtpsession) gst_rtp_session_chain_send_rtp_list); gst_pad_set_getcaps_function (rtpsession->send_rtp_sink, gst_rtp_session_getcaps_send_rtp); - gst_pad_set_setcaps_function (rtpsession->send_rtp_sink, - gst_rtp_session_setcaps_send_rtp); gst_pad_set_event_function (rtpsession->send_rtp_sink, (GstPadEventFunction) gst_rtp_session_event_send_rtp_sink); gst_pad_set_iterate_internal_links_function (rtpsession->send_rtp_sink, @@ -2064,7 +2063,7 @@ remove_send_rtcp_src (GstRtpSession * rtpsession) static GstPad * gst_rtp_session_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name) + GstPadTemplate * templ, const gchar * name, const GstCaps * caps) { GstRtpSession *rtpsession; GstElementClass *klass; diff --git a/gst/rtpmanager/gstrtpssrcdemux.c b/gst/rtpmanager/gstrtpssrcdemux.c index 25ab9c3485..4527b8f605 100644 --- a/gst/rtpmanager/gstrtpssrcdemux.c +++ b/gst/rtpmanager/gstrtpssrcdemux.c @@ -95,9 +95,8 @@ enum LAST_SIGNAL }; -GST_BOILERPLATE (GstRtpSsrcDemux, gst_rtp_ssrc_demux, GstElement, - GST_TYPE_ELEMENT); - +#define gst_rtp_ssrc_demux_parent_class parent_class +G_DEFINE_TYPE (GstRtpSsrcDemux, gst_rtp_ssrc_demux, GST_TYPE_ELEMENT); /* GObject vmethods */ static void gst_rtp_ssrc_demux_dispose (GObject * object); @@ -164,6 +163,7 @@ find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc) GstPadTemplate *templ; gchar *padname; GstRtpSsrcDemuxPad *demuxpad; + GstCaps *caps; GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc); @@ -198,9 +198,13 @@ find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc) demux->srcpads = g_slist_prepend (demux->srcpads, demuxpad); /* copy caps from input */ - gst_pad_set_caps (rtp_pad, GST_PAD_CAPS (demux->rtp_sink)); + caps = gst_pad_get_current_caps (demux->rtp_sink); + gst_pad_set_caps (rtp_pad, caps); + gst_caps_unref (caps); gst_pad_use_fixed_caps (rtp_pad); - gst_pad_set_caps (rtcp_pad, GST_PAD_CAPS (demux->rtcp_sink)); + caps = gst_pad_get_current_caps (demux->rtcp_sink); + gst_pad_set_caps (rtcp_pad, caps); + gst_caps_unref (caps); gst_pad_use_fixed_caps (rtcp_pad); gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event); @@ -225,26 +229,6 @@ find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc) return demuxpad; } -static void -gst_rtp_ssrc_demux_base_init (gpointer g_class) -{ - GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_src_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_src_template)); - - gst_element_class_set_details_simple (gstelement_klass, "RTP SSRC Demux", - "Demux/Network/RTP", - "Splits RTP streams based on the SSRC", - "Wim Taymans "); -} - static void gst_rtp_ssrc_demux_class_init (GstRtpSsrcDemuxClass * klass) { @@ -307,13 +291,26 @@ gst_rtp_ssrc_demux_class_init (GstRtpSsrcDemuxClass * klass) gstrtpssrcdemux_klass->clear_ssrc = GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_clear_ssrc); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&rtp_ssrc_demux_sink_template)); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_sink_template)); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&rtp_ssrc_demux_src_template)); + gst_element_class_add_pad_template (gstelement_klass, + gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_src_template)); + + gst_element_class_set_details_simple (gstelement_klass, "RTP SSRC Demux", + "Demux/Network/RTP", + "Splits RTP streams based on the SSRC", + "Wim Taymans "); + GST_DEBUG_CATEGORY_INIT (gst_rtp_ssrc_demux_debug, "rtpssrcdemux", 0, "RTP SSRC demuxer"); } static void -gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux, - GstRtpSsrcDemuxClass * g_class) +gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux) { GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux); @@ -437,7 +434,6 @@ gst_rtp_ssrc_demux_sink_event (GstPad * pad, GstEvent * event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED); - case GST_EVENT_NEWSEGMENT: default: { GSList *walk; @@ -481,7 +477,6 @@ gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad, GstEvent * event) demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: default: { GSList *walk; @@ -518,13 +513,16 @@ gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf) GstRtpSsrcDemux *demux; guint32 ssrc; GstRtpSsrcDemuxPad *dpad; + GstRTPBuffer rtp; demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad)); if (!gst_rtp_buffer_validate (buf)) goto invalid_payload; - ssrc = gst_rtp_buffer_get_ssrc (buf); + gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp); + ssrc = gst_rtp_buffer_get_ssrc (&rtp); + gst_rtp_buffer_unmap (&rtp); GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc); @@ -563,14 +561,18 @@ gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf) guint32 ssrc; GstRtpSsrcDemuxPad *dpad; GstRTCPPacket packet; + GstRTCPBuffer rtcp; demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad)); if (!gst_rtcp_buffer_validate (buf)) goto invalid_rtcp; - if (!gst_rtcp_buffer_get_first_packet (buf, &packet)) + gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp); + if (!gst_rtcp_buffer_get_first_packet (&rtcp, &packet)) { + gst_rtcp_buffer_unmap (&rtcp); goto invalid_rtcp; + } /* first packet must be SR or RR or else the validate would have failed */ switch (gst_rtcp_packet_get_type (&packet)) { @@ -582,6 +584,7 @@ gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf) default: goto unexpected_rtcp; } + gst_rtcp_buffer_unmap (&rtcp); GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc); @@ -639,11 +642,13 @@ gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event) GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) walk->data; if (dpad->rtp_pad == pad || dpad->rtcp_pad == pad) { + GstStructure *ws; + event = GST_EVENT_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (event))); - gst_structure_set (event->structure, "ssrc", G_TYPE_UINT, - dpad->ssrc, NULL); + ws = gst_event_writable_structure (event); + gst_structure_set (ws, "ssrc", G_TYPE_UINT, dpad->ssrc, NULL); break; } } @@ -683,8 +688,15 @@ gst_rtp_ssrc_demux_iterate_internal_links_src (GstPad * pad) break; } } - it = gst_iterator_new_single (GST_TYPE_PAD, otherpad, - (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref); + if (otherpad) { + GValue val = { 0, }; + + g_value_init (&val, GST_TYPE_PAD); + g_value_set_object (&val, otherpad); + it = gst_iterator_new_single (GST_TYPE_PAD, &val); + g_value_unset (&val); + gst_object_unref (otherpad); + } GST_PAD_UNLOCK (demux); gst_object_unref (demux); diff --git a/gst/rtpmanager/rtpjitterbuffer.c b/gst/rtpmanager/rtpjitterbuffer.c index f6382fc614..73b09d4a6c 100644 --- a/gst/rtpmanager/rtpjitterbuffer.c +++ b/gst/rtpmanager/rtpjitterbuffer.c @@ -608,18 +608,24 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf, GList *list; guint32 rtptime; guint16 seqnum; + GstRTPBuffer rtp; g_return_val_if_fail (jbuf != NULL, FALSE); g_return_val_if_fail (buf != NULL, FALSE); - seqnum = gst_rtp_buffer_get_seq (buf); + gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp); + + seqnum = gst_rtp_buffer_get_seq (&rtp); /* loop the list to skip strictly smaller seqnum buffers */ for (list = jbuf->packets->head; list; list = g_list_next (list)) { guint16 qseq; gint gap; + GstRTPBuffer rtpb; - qseq = gst_rtp_buffer_get_seq (GST_BUFFER_CAST (list->data)); + gst_rtp_buffer_map (GST_BUFFER_CAST (list->data), GST_MAP_READ, &rtpb); + qseq = gst_rtp_buffer_get_seq (&rtpb); + gst_rtp_buffer_unmap (&rtpb); /* compare the new seqnum to the one in the buffer */ gap = gst_rtp_buffer_compare_seqnum (seqnum, qseq); @@ -633,7 +639,7 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf, break; } - rtptime = gst_rtp_buffer_get_timestamp (buf); + rtptime = gst_rtp_buffer_get_timestamp (&rtp); switch (jbuf->mode) { case RTP_JITTER_BUFFER_MODE_NONE: case RTP_JITTER_BUFFER_MODE_BUFFER: @@ -673,11 +679,14 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf, if (G_LIKELY (tail)) *tail = (list == NULL); + gst_rtp_buffer_unmap (&rtp); + return TRUE; /* ERRORS */ duplicate: { + gst_rtp_buffer_unmap (&rtp); GST_WARNING ("duplicate packet %d found", (gint) seqnum); return FALSE; } @@ -834,6 +843,7 @@ rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer * jbuf) guint64 high_ts, low_ts; GstBuffer *high_buf, *low_buf; guint32 result; + GstRTPBuffer rtp; g_return_val_if_fail (jbuf != NULL, 0); @@ -843,8 +853,12 @@ rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer * jbuf) if (!high_buf || !low_buf || high_buf == low_buf) return 0; - high_ts = gst_rtp_buffer_get_timestamp (high_buf); - low_ts = gst_rtp_buffer_get_timestamp (low_buf); + gst_rtp_buffer_map (high_buf, GST_MAP_READ, &rtp); + high_ts = gst_rtp_buffer_get_timestamp (&rtp); + gst_rtp_buffer_unmap (&rtp); + gst_rtp_buffer_map (low_buf, GST_MAP_READ, &rtp); + low_ts = gst_rtp_buffer_get_timestamp (&rtp); + gst_rtp_buffer_unmap (&rtp); /* it needs to work if ts wraps */ if (high_ts >= low_ts) { diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 77c5594f28..bc483c3f6b 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -158,7 +158,7 @@ gst_rtp_bin_marshal_BOOLEAN__MINIOBJECT_BOOLEAN (GClosure * closure, cc->callback); v_return = callback (data1, - gst_value_get_mini_object (param_values + 1), + g_value_get_boxed (param_values + 1), g_value_get_boolean (param_values + 2), data2); g_value_set_boolean (return_value, v_return); @@ -195,7 +195,7 @@ gst_rtp_bin_marshal_VOID__UINT_UINT_UINT_UINT_MINIOBJECT (GClosure * closure, g_value_get_uint (param_values + 2), g_value_get_uint (param_values + 3), g_value_get_uint (param_values + 4), - gst_value_get_mini_object (param_values + 5), data2); + g_value_get_boxed (param_values + 5), data2); } @@ -1670,6 +1670,7 @@ update_arrival_stats (RTPSession * sess, RTPArrivalStats * arrival, GstClockTime running_time, guint64 ntpnstime) { GstMetaNetAddress *meta; + GstRTPBuffer rtpb; /* get time of arrival */ arrival->current_time = current_time; @@ -1677,10 +1678,12 @@ update_arrival_stats (RTPSession * sess, RTPArrivalStats * arrival, arrival->ntpnstime = ntpnstime; /* get packet size including header overhead */ - arrival->bytes = GST_BUFFER_SIZE (buffer) + sess->header_len; + arrival->bytes = gst_buffer_get_size (buffer) + sess->header_len; if (rtp) { - arrival->payload_len = gst_rtp_buffer_get_payload_len (buffer); + gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpb); + arrival->payload_len = gst_rtp_buffer_get_payload_len (&rtpb); + gst_rtp_buffer_unmap (&rtpb); } else { arrival->payload_len = 0; } @@ -1720,6 +1723,7 @@ rtp_session_process_rtp (RTPSession * sess, GstBuffer * buffer, guint32 csrcs[16]; guint8 i, count; guint64 oldrate; + GstRTPBuffer rtp; g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); @@ -1737,23 +1741,28 @@ rtp_session_process_rtp (RTPSession * sess, GstBuffer * buffer, goto ignore; /* get SSRC and look up in session database */ - ssrc = gst_rtp_buffer_get_ssrc (buffer); + gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp); + ssrc = gst_rtp_buffer_get_ssrc (&rtp); source = obtain_source (sess, ssrc, &created, &arrival, TRUE); - if (!source) + if (!source) { + gst_rtp_buffer_unmap (&rtp); goto collision; - - prevsender = RTP_SOURCE_IS_SENDER (source); - prevactive = RTP_SOURCE_IS_ACTIVE (source); - oldrate = source->bitrate; + } /* copy available csrc for later */ - count = gst_rtp_buffer_get_csrc_count (buffer); + count = gst_rtp_buffer_get_csrc_count (&rtp); /* make sure to not overflow our array. An RTP buffer can maximally contain * 16 CSRCs */ count = MIN (count, 16); for (i = 0; i < count; i++) - csrcs[i] = gst_rtp_buffer_get_csrc (buffer, i); + csrcs[i] = gst_rtp_buffer_get_csrc (&rtp, i); + + gst_rtp_buffer_unmap (&rtp); + + prevsender = RTP_SOURCE_IS_SENDER (source); + prevactive = RTP_SOURCE_IS_ACTIVE (source); + oldrate = source->bitrate; /* let source process the packet */ result = rtp_source_process_rtp (source, buffer, &arrival); @@ -2191,8 +2200,8 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, GstBuffer *fci_buffer = NULL; if (fci_length > 0) { - fci_buffer = gst_buffer_create_sub (packet->buffer, - fci_data - GST_BUFFER_DATA (packet->buffer), fci_length); + fci_buffer = gst_buffer_copy_region (packet->rtcp->buffer, + GST_BUFFER_COPY_MEMORY, fci_data - packet->rtcp->data, fci_length); GST_BUFFER_TIMESTAMP (fci_buffer) = arrival->running_time; } @@ -2252,6 +2261,7 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, gboolean more, is_bye = FALSE, do_sync = FALSE; RTPArrivalStats arrival; GstFlowReturn result = GST_FLOW_OK; + GstRTCPBuffer rtcp; g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); @@ -2270,7 +2280,8 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, goto ignore; /* start processing the compound packet */ - more = gst_rtcp_buffer_get_first_packet (buffer, &packet); + gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcp); + more = gst_rtcp_buffer_get_first_packet (&rtcp, &packet); while (more) { GstRTCPType type; @@ -2313,6 +2324,8 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, more = gst_rtcp_packet_move_to_next (&packet); } + gst_rtcp_buffer_unmap (&rtcp); + /* if we are scheduling a BYE, we only want to count bye packets, else we * count everything */ if (sess->source->received_bye) { @@ -2331,7 +2344,7 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, /* notify caller of sr packets in the callback */ if (do_sync && sess->callbacks.sync_rtcp) { /* make writable, we might want to change the buffer */ - buffer = gst_buffer_make_metadata_writable (buffer); + buffer = gst_buffer_make_writable (buffer); result = sess->callbacks.sync_rtcp (sess, sess->source, buffer, sess->sync_rtcp_user_data); @@ -2383,7 +2396,12 @@ rtp_session_send_rtp (RTPSession * sess, gpointer data, gboolean is_list, g_return_val_if_fail (is_list || GST_IS_BUFFER (data), GST_FLOW_ERROR); if (is_list) { - valid_packet = gst_rtp_buffer_list_validate (GST_BUFFER_LIST_CAST (data)); + GstBufferList *blist = GST_BUFFER_LIST_CAST (data); + gint i, len = gst_buffer_list_len (blist); + + valid_packet = TRUE; + for (i = 0; i < len; i++) + valid_packet &= gst_rtp_buffer_validate (gst_buffer_list_get (blist, i)); } else { valid_packet = gst_rtp_buffer_validate (GST_BUFFER_CAST (data)); } @@ -2641,9 +2659,12 @@ session_start_rtcp (RTPSession * sess, ReportData * data) { GstRTCPPacket *packet = &data->packet; RTPSource *own = sess->source; + GstRTCPBuffer rtcp; data->rtcp = gst_rtcp_buffer_new (sess->mtu); + gst_rtcp_buffer_map (data->rtcp, GST_MAP_WRITE, &rtcp); + if (RTP_SOURCE_IS_SENDER (own)) { guint64 ntptime; guint32 rtptime; @@ -2651,7 +2672,7 @@ session_start_rtcp (RTPSession * sess, ReportData * data) /* we are a sender, create SR */ GST_DEBUG ("create SR for SSRC %08x", own->ssrc); - gst_rtcp_buffer_add_packet (data->rtcp, GST_RTCP_TYPE_SR, packet); + gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_SR, packet); /* get latest stats */ rtp_source_get_new_sr (own, data->ntpnstime, data->running_time, @@ -2666,9 +2687,11 @@ session_start_rtcp (RTPSession * sess, ReportData * data) } else { /* we are only receiver, create RR */ GST_DEBUG ("create RR for SSRC %08x", own->ssrc); - gst_rtcp_buffer_add_packet (data->rtcp, GST_RTCP_TYPE_RR, packet); + gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_RR, packet); gst_rtcp_packet_rr_set_ssrc (packet, own->ssrc); } + + gst_rtcp_buffer_unmap (&rtcp); } /* construct a Sender or Receiver Report */ @@ -2792,9 +2815,12 @@ session_sdes (RTPSession * sess, ReportData * data) GstRTCPPacket *packet = &data->packet; const GstStructure *sdes; gint i, n_fields; + GstRTCPBuffer rtcp; + + gst_rtcp_buffer_map (data->rtcp, GST_MAP_WRITE, &rtcp); /* add SDES packet */ - gst_rtcp_buffer_add_packet (data->rtcp, GST_RTCP_TYPE_SDES, packet); + gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_SDES, packet); gst_rtcp_packet_sdes_add_item (packet, sess->source->ssrc); @@ -2848,6 +2874,8 @@ session_sdes (RTPSession * sess, ReportData * data) } data->has_sdes = TRUE; + + gst_rtcp_buffer_unmap (&rtcp); } /* schedule a BYE packet */ @@ -2855,6 +2883,7 @@ static void session_bye (RTPSession * sess, ReportData * data) { GstRTCPPacket *packet = &data->packet; + GstRTCPBuffer rtcp; /* open packet */ session_start_rtcp (sess, data); @@ -2862,14 +2891,18 @@ session_bye (RTPSession * sess, ReportData * data) /* add SDES */ session_sdes (sess, data); + gst_rtcp_buffer_map (data->rtcp, GST_MAP_WRITE, &rtcp); + /* add a BYE packet */ - gst_rtcp_buffer_add_packet (data->rtcp, GST_RTCP_TYPE_BYE, packet); + gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_BYE, packet); gst_rtcp_packet_bye_add_ssrc (packet, sess->source->ssrc); if (sess->bye_reason) gst_rtcp_packet_bye_set_reason (packet, sess->bye_reason); /* we have a BYE packet now */ data->is_bye = TRUE; + + gst_rtcp_buffer_unmap (&rtcp); } static gboolean @@ -3090,10 +3123,7 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time, if (sess->callbacks.send_rtcp && (do_not_suppress || !data.may_suppress)) { guint packet_size; - /* close the RTCP packet */ - gst_rtcp_buffer_end (data.rtcp); - - packet_size = GST_BUFFER_SIZE (data.rtcp) + sess->header_len; + packet_size = gst_buffer_get_size (data.rtcp) + sess->header_len; UPDATE_AVG (sess->stats.avg_rtcp_packet_size, packet_size); GST_DEBUG ("%p, sending RTCP packet, avg size %u, %u", &sess->stats, @@ -3189,15 +3219,20 @@ static gboolean has_pli_compare_func (gconstpointer a, gconstpointer ignored) { GstRTCPPacket packet; + GstRTCPBuffer rtcp; + gboolean ret = FALSE; - packet.buffer = (GstBuffer *) a; - packet.offset = 0; + gst_rtcp_buffer_map ((GstBuffer *) a, GST_MAP_READ, &rtcp); - if (gst_rtcp_packet_get_type (&packet) == GST_RTCP_TYPE_PSFB && - gst_rtcp_packet_fb_get_type (&packet) == GST_RTCP_PSFB_TYPE_PLI) - return TRUE; - else - return FALSE; + if (gst_rtcp_buffer_get_first_packet (&rtcp, &packet)) { + if (gst_rtcp_packet_get_type (&packet) == GST_RTCP_TYPE_PSFB && + gst_rtcp_packet_fb_get_type (&packet) == GST_RTCP_PSFB_TYPE_PLI) + ret = TRUE; + } + + gst_rtcp_buffer_unmap (&rtcp); + + return ret; } static gboolean @@ -3216,16 +3251,21 @@ rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer, if (media_src && !rtp_source_has_retained (media_src, has_pli_compare_func, NULL)) { - if (gst_rtcp_buffer_add_packet (buffer, GST_RTCP_TYPE_PSFB, &rtcppacket)) { + GstRTCPBuffer rtcp; + + gst_rtcp_buffer_map (buffer, GST_MAP_WRITE, &rtcp); + if (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_PSFB, &rtcppacket)) { gst_rtcp_packet_fb_set_type (&rtcppacket, GST_RTCP_PSFB_TYPE_PLI); gst_rtcp_packet_fb_set_sender_ssrc (&rtcppacket, rtp_source_get_ssrc (sess->source)); gst_rtcp_packet_fb_set_media_ssrc (&rtcppacket, media_ssrc); ret = TRUE; + gst_rtcp_buffer_unmap (&rtcp); } else { /* Break because the packet is full, will put next request in a * further packet */ + gst_rtcp_buffer_unmap (&rtcp); break; } } diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c index fb9e039553..2912708c23 100644 --- a/gst/rtpmanager/rtpsource.c +++ b/gst/rtpmanager/rtpsource.c @@ -897,20 +897,24 @@ calculate_jitter (RTPSource * src, GstBuffer * buffer, gint32 diff; gint clock_rate; guint8 pt; + GstRTPBuffer rtp; /* get arrival time */ if ((running_time = arrival->running_time) == GST_CLOCK_TIME_NONE) goto no_time; - pt = gst_rtp_buffer_get_payload_type (buffer); + gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp); + pt = gst_rtp_buffer_get_payload_type (&rtp); GST_LOG ("SSRC %08x got payload %d", src->ssrc, pt); /* get clockrate */ - if ((clock_rate = get_clock_rate (src, pt)) == -1) + if ((clock_rate = get_clock_rate (src, pt)) == -1) { + gst_rtp_buffer_unmap (&rtp); goto no_clock_rate; + } - rtptime = gst_rtp_buffer_get_timestamp (buffer); + rtptime = gst_rtp_buffer_get_timestamp (&rtp); /* convert arrival time to RTP timestamp units, truncate to 32 bits, we don't * care about the absolute value, just the difference. */ @@ -939,6 +943,7 @@ calculate_jitter (RTPSource * src, GstBuffer * buffer, GST_LOG ("rtparrival %u, rtptime %u, clock-rate %d, diff %d, jitter: %f", rtparrival, rtptime, clock_rate, diff, (src->stats.jitter) / 16.0); + gst_rtp_buffer_unmap (&rtp); return; /* ERRORS */ @@ -1021,15 +1026,21 @@ rtp_source_process_rtp (RTPSource * src, GstBuffer * buffer, guint16 seqnr, udelta; RTPSourceStats *stats; guint16 expected; + GstRTPBuffer rtp; g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR); g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); stats = &src->stats; - seqnr = gst_rtp_buffer_get_seq (buffer); + gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp); + seqnr = gst_rtp_buffer_get_seq (&rtp); + gst_rtp_buffer_unmap (&rtp); - rtp_source_update_caps (src, GST_BUFFER_CAPS (buffer)); + /* FIXME-0.11 + * would be nice to be able to pass along with buffer */ + g_assert_not_reached (); + /* rtp_source_update_caps (src, GST_BUFFER_CAPS (buffer)); */ if (stats->cycles == -1) { GST_DEBUG ("received first buffer"); @@ -1157,12 +1168,16 @@ rtp_source_process_bye (RTPSource * src, const gchar * reason) src->received_bye = TRUE; } -static GstBufferListItem -set_ssrc (GstBuffer ** buffer, guint group, guint idx, RTPSource * src) +static gboolean +set_ssrc (GstBuffer ** buffer, guint idx, RTPSource * src) { + GstRTPBuffer rtp; + *buffer = gst_buffer_make_writable (*buffer); - gst_rtp_buffer_set_ssrc (*buffer, src->ssrc); - return GST_BUFFER_LIST_SKIP_GROUP; + gst_rtp_buffer_map (*buffer, GST_MAP_WRITE, &rtp); + gst_rtp_buffer_set_ssrc (&rtp, src->ssrc); + gst_rtp_buffer_unmap (&rtp); + return TRUE; } /** @@ -1191,6 +1206,7 @@ rtp_source_send_rtp (RTPSource * src, gpointer data, gboolean is_list, GstBuffer *buffer = NULL; guint packets; guint32 ssrc; + GstRTPBuffer rtp; g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR); g_return_val_if_fail (is_list || GST_IS_BUFFER (data), GST_FLOW_ERROR); @@ -1200,24 +1216,36 @@ rtp_source_send_rtp (RTPSource * src, gpointer data, gboolean is_list, /* We can grab the caps from the first group, since all * groups of a buffer list have same caps. */ - buffer = gst_buffer_list_get (list, 0, 0); + buffer = gst_buffer_list_get (list, 0); if (!buffer) goto no_buffer; } else { buffer = GST_BUFFER_CAST (data); } - rtp_source_update_caps (src, GST_BUFFER_CAPS (buffer)); + + /* FIXME-0.11 */ + g_assert_not_reached (); + /* rtp_source_update_caps (src, GST_BUFFER_CAPS (buffer)); */ /* we are a sender now */ src->is_sender = TRUE; if (is_list) { + gint i; + /* Each group makes up a network packet. */ - packets = gst_buffer_list_n_groups (list); - len = gst_rtp_buffer_list_get_payload_len (list); + packets = gst_buffer_list_len (list); + for (i = 0, len = 0; i < packets; i++) { + gst_rtp_buffer_map (gst_buffer_list_get (list, i), GST_MAP_READ, &rtp); + len += gst_rtp_buffer_get_payload_len (&rtp); + gst_rtp_buffer_unmap (&rtp); + } + /* subsequent info taken from first list member */ + gst_rtp_buffer_map (gst_buffer_list_get (list, 0), GST_MAP_READ, &rtp); } else { packets = 1; - len = gst_rtp_buffer_get_payload_len (buffer); + gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp); + len = gst_rtp_buffer_get_payload_len (&rtp); } /* update stats for the SR */ @@ -1227,11 +1255,7 @@ rtp_source_send_rtp (RTPSource * src, gpointer data, gboolean is_list, do_bitrate_estimation (src, running_time, &src->bytes_sent); - if (is_list) { - rtptime = gst_rtp_buffer_list_get_timestamp (list); - } else { - rtptime = gst_rtp_buffer_get_timestamp (buffer); - } + rtptime = gst_rtp_buffer_get_timestamp (&rtp); ext_rtptime = src->last_rtptime; ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime); @@ -1255,15 +1279,14 @@ rtp_source_send_rtp (RTPSource * src, gpointer data, gboolean is_list, src->last_rtptime = ext_rtptime; /* push packet */ - if (!src->callbacks.push_rtp) + if (!src->callbacks.push_rtp) { + gst_rtp_buffer_unmap (&rtp); goto no_callback; - - if (is_list) { - ssrc = gst_rtp_buffer_list_get_ssrc (list); - } else { - ssrc = gst_rtp_buffer_get_ssrc (buffer); } + ssrc = gst_rtp_buffer_get_ssrc (&rtp); + gst_rtp_buffer_unmap (&rtp); + if (ssrc != src->ssrc) { /* the SSRC of the packet is not correct, make a writable buffer and * update the SSRC. This could involve a complete copy of the packet when @@ -1279,7 +1302,7 @@ rtp_source_send_rtp (RTPSource * src, gpointer data, gboolean is_list, list = gst_buffer_list_make_writable (list); gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc, src); } else { - set_ssrc (&buffer, 0, 0, src); + set_ssrc (&buffer, 0, src); } } GST_LOG ("pushing RTP %s %" G_GUINT64_FORMAT, is_list ? "list" : "packet", @@ -1780,8 +1803,8 @@ rtp_source_retain_rtcp_packet (RTPSource * src, GstRTCPPacket * packet, { GstBuffer *buffer; - buffer = gst_buffer_create_sub (packet->buffer, packet->offset, - (gst_rtcp_packet_get_length (packet) + 1) * 4); + buffer = gst_buffer_copy_region (packet->rtcp->buffer, GST_BUFFER_COPY_MEMORY, + packet->offset, (gst_rtcp_packet_get_length (packet) + 1) * 4); GST_BUFFER_TIMESTAMP (buffer) = running_time;