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.
This commit is contained in:
Mark Nauwelaerts 2011-07-06 10:11:52 +02:00
parent 794320a202
commit ef02634dc6
6 changed files with 298 additions and 214 deletions

View File

@ -117,7 +117,8 @@ enum
LAST_SIGNAL 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); 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 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 <kai.vehmanen@nokia.com>");
}
static void static void
gst_rtp_pt_demux_class_init (GstRtpPtDemuxClass * klass) 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); 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 <kai.vehmanen@nokia.com>");
GST_DEBUG_CATEGORY_INIT (gst_rtp_pt_demux_debug, GST_DEBUG_CATEGORY_INIT (gst_rtp_pt_demux_debug,
"rtpptdemux", 0, "RTP codec demuxer"); "rtpptdemux", 0, "RTP codec demuxer");
} }
static void 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); 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); caps = g_value_dup_boxed (&ret);
g_value_unset (&ret); g_value_unset (&ret);
if (caps == NULL) { if (caps == NULL) {
caps = GST_PAD_CAPS (rtpdemux->sink); caps = gst_pad_get_current_caps (rtpdemux->sink);
if (caps)
gst_caps_ref (caps);
} }
GST_DEBUG ("pt %d, got caps %" GST_PTR_FORMAT, pt, caps); 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; GstPad *srcpad;
GstRtpPtDemuxPad *rtpdemuxpad; GstRtpPtDemuxPad *rtpdemuxpad;
GstCaps *caps; GstCaps *caps;
GstRTPBuffer rtp;
rtpdemux = GST_RTP_PT_DEMUX (GST_OBJECT_PARENT (pad)); rtpdemux = GST_RTP_PT_DEMUX (GST_OBJECT_PARENT (pad));
if (!gst_rtp_buffer_validate (buf)) if (!gst_rtp_buffer_validate (buf))
goto invalid_buffer; 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); 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; rtpdemuxpad->newcaps = FALSE;
} }
gst_buffer_set_caps (buf, GST_PAD_CAPS (srcpad));
/* push to srcpad */ /* push to srcpad */
ret = gst_pad_push (srcpad, buf); 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; GstRtpPtDemuxPad *dpad = (GstRtpPtDemuxPad *) walk->data;
if (dpad->pad == pad) { if (dpad->pad == pad) {
GstStructure *ws;
event = event =
GST_EVENT_CAST (gst_mini_object_make_writable GST_EVENT_CAST (gst_mini_object_make_writable
(GST_MINI_OBJECT_CAST (event))); (GST_MINI_OBJECT_CAST (event)));
gst_structure_set (event->structure, ws = gst_event_writable_structure (event);
"payload", G_TYPE_UINT, dpad->pt, NULL); gst_structure_set (ws, "payload", G_TYPE_UINT, dpad->pt, NULL);
break; break;
} }
} }

View File

@ -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, static GstStateChangeReturn gst_rtp_session_change_state (GstElement * element,
GstStateChange transition); GstStateChange transition);
static GstPad *gst_rtp_session_request_new_pad (GstElement * element, 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 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 void gst_rtp_session_clear_pt_map (GstRtpSession * rtpsession);
static guint gst_rtp_session_signals[LAST_SIGNAL] = { 0 }; static guint gst_rtp_session_signals[LAST_SIGNAL] = { 0 };
@ -365,35 +368,8 @@ on_sender_timeout (RTPSession * session, RTPSource * src, GstRtpSession * sess)
src->ssrc); src->ssrc);
} }
GST_BOILERPLATE (GstRtpSession, gst_rtp_session, GstElement, GST_TYPE_ELEMENT); #define gst_rtp_session_parent_class parent_class
G_DEFINE_TYPE (GstRtpSession, gst_rtp_session, 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 <wim.taymans@gmail.com>");
}
static void static void
gst_rtp_session_class_init (GstRtpSessionClass * klass) 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); 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 <wim.taymans@gmail.com>");
GST_DEBUG_CATEGORY_INIT (gst_rtp_session_debug, GST_DEBUG_CATEGORY_INIT (gst_rtp_session_debug,
"rtpsession", 0, "RTP Session"); "rtpsession", 0, "RTP Session");
} }
static void 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 = GST_RTP_SESSION_GET_PRIVATE (rtpsession);
rtpsession->priv->lock = g_mutex_new (); rtpsession->priv->lock = g_mutex_new ();
@ -977,7 +975,7 @@ gst_rtp_session_change_state (GstElement * element, GstStateChange transition)
break; break;
} }
res = parent_class->change_state (element, transition); res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
@ -1099,12 +1097,10 @@ gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src,
GstCaps *caps; GstCaps *caps;
/* set rtcp caps on output pad */ /* 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); caps = gst_caps_new_simple ("application/x-rtcp", NULL);
gst_pad_set_caps (rtcp_src, caps); gst_pad_set_caps (rtcp_src, caps);
} else }
gst_caps_ref (caps);
gst_buffer_set_caps (buffer, caps);
gst_caps_unref (caps); gst_caps_unref (caps);
gst_object_ref (rtcp_src); gst_object_ref (rtcp_src);
@ -1158,12 +1154,10 @@ gst_rtp_session_sync_rtcp (RTPSession * sess, RTPSource * src,
GstCaps *caps; GstCaps *caps;
/* set rtcp caps on output pad */ /* 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); caps = gst_caps_new_simple ("application/x-rtcp", NULL);
gst_pad_set_caps (sync_src, caps); gst_pad_set_caps (sync_src, caps);
} else }
gst_caps_ref (caps);
gst_buffer_set_caps (buffer, caps);
gst_caps_unref (caps); gst_caps_unref (caps);
gst_object_ref (sync_src); 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)); GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (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: case GST_EVENT_FLUSH_STOP:
gst_segment_init (&rtpsession->recv_rtp_seg, GST_FORMAT_UNDEFINED); gst_segment_init (&rtpsession->recv_rtp_seg, GST_FORMAT_UNDEFINED);
ret = gst_pad_push_event (rtpsession->recv_rtp_src, event); ret = gst_pad_push_event (rtpsession->recv_rtp_src, event);
break; break;
case GST_EVENT_NEWSEGMENT: case GST_EVENT_SEGMENT:
{ {
gboolean update; GstSegment *segment, in_segment;
gdouble rate, arate;
GstFormat format;
gint64 start, stop, time;
GstSegment *segment;
segment = &rtpsession->recv_rtp_seg; segment = &rtpsession->recv_rtp_seg;
/* the newsegment event is needed to convert the RTP timestamp to /* the newsegment event is needed to convert the RTP timestamp to
* running_time, which is needed to generate a mapping from RTP to NTP * running_time, which is needed to generate a mapping from RTP to NTP
* timestamps in SR reports */ * timestamps in SR reports */
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, gst_event_copy_segment (event, &in_segment);
&start, &stop, &time); GST_DEBUG_OBJECT (rtpsession, "received segment %" GST_SEGMENT_FORMAT,
in_segment);
GST_DEBUG_OBJECT (rtpsession, /* accept upstream */
"configured NEWSEGMENT update %d, rate %lf, applied rate %lf, " gst_segment_copy_into (&in_segment, segment);
"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);
/* push event forward */ /* push event forward */
ret = gst_pad_push_event (rtpsession->recv_rtp_src, event); 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); GST_RTP_SESSION_UNLOCK (rtpsession);
if (otherpad) { if (otherpad) {
it = gst_iterator_new_single (GST_TYPE_PAD, otherpad, GValue val = { 0, };
(GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref);
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_object_unref (otherpad);
} }
@ -1664,36 +1661,35 @@ gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstEvent * event)
GST_DEBUG_OBJECT (rtpsession, "received event"); GST_DEBUG_OBJECT (rtpsession, "received event");
switch (GST_EVENT_TYPE (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: case GST_EVENT_FLUSH_STOP:
gst_segment_init (&rtpsession->send_rtp_seg, GST_FORMAT_UNDEFINED); gst_segment_init (&rtpsession->send_rtp_seg, GST_FORMAT_UNDEFINED);
ret = gst_pad_push_event (rtpsession->send_rtp_src, event); ret = gst_pad_push_event (rtpsession->send_rtp_src, event);
break; break;
case GST_EVENT_NEWSEGMENT:{ case GST_EVENT_SEGMENT:{
gboolean update; GstSegment *segment, in_segment;
gdouble rate, arate;
GstFormat format;
gint64 start, stop, time;
GstSegment *segment;
segment = &rtpsession->send_rtp_seg; segment = &rtpsession->send_rtp_seg;
/* the newsegment event is needed to convert the RTP timestamp to /* the newsegment event is needed to convert the RTP timestamp to
* running_time, which is needed to generate a mapping from RTP to NTP * running_time, which is needed to generate a mapping from RTP to NTP
* timestamps in SR reports */ * timestamps in SR reports */
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, gst_event_copy_segment (event, &in_segment);
&start, &stop, &time); GST_DEBUG_OBJECT (rtpsession, "received segment %" GST_SEGMENT_FORMAT,
in_segment);
GST_DEBUG_OBJECT (rtpsession, /* accept upstream */
"configured NEWSEGMENT update %d, rate %lf, applied rate %lf, " gst_segment_copy_into (&in_segment, segment);
"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);
/* push event forward */ /* push event forward */
ret = gst_pad_push_event (rtpsession->send_rtp_src, event); 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 * static GstCaps *
gst_rtp_session_getcaps_send_rtp (GstPad * pad) gst_rtp_session_getcaps_send_rtp (GstPad * pad, GstCaps * filter)
{ {
GstRtpSession *rtpsession; GstRtpSession *rtpsession;
GstRtpSessionPrivate *priv; GstRtpSessionPrivate *priv;
@ -1754,6 +1750,13 @@ gst_rtp_session_getcaps_send_rtp (GstPad * pad)
result = gst_caps_new_full (s1, s2, NULL); 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_DEBUG_OBJECT (rtpsession, "getting caps %" GST_PTR_FORMAT, result);
gst_object_unref (rtpsession); 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. /* All groups in an list have the same timestamp.
* So, just take it from the first group. */ * 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) if (buffer)
timestamp = GST_BUFFER_TIMESTAMP (buffer); timestamp = GST_BUFFER_TIMESTAMP (buffer);
else else
@ -1872,8 +1875,6 @@ create_recv_rtp_sink (GstRtpSession * rtpsession)
gst_rtp_session_chain_recv_rtp); gst_rtp_session_chain_recv_rtp);
gst_pad_set_event_function (rtpsession->recv_rtp_sink, gst_pad_set_event_function (rtpsession->recv_rtp_sink,
(GstPadEventFunction) gst_rtp_session_event_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_pad_set_iterate_internal_links_function (rtpsession->recv_rtp_sink,
gst_rtp_session_iterate_internal_links); gst_rtp_session_iterate_internal_links);
gst_pad_set_active (rtpsession->recv_rtp_sink, TRUE); 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_rtp_session_chain_send_rtp_list);
gst_pad_set_getcaps_function (rtpsession->send_rtp_sink, gst_pad_set_getcaps_function (rtpsession->send_rtp_sink,
gst_rtp_session_getcaps_send_rtp); 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, gst_pad_set_event_function (rtpsession->send_rtp_sink,
(GstPadEventFunction) gst_rtp_session_event_send_rtp_sink); (GstPadEventFunction) gst_rtp_session_event_send_rtp_sink);
gst_pad_set_iterate_internal_links_function (rtpsession->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 * static GstPad *
gst_rtp_session_request_new_pad (GstElement * element, gst_rtp_session_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name) GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{ {
GstRtpSession *rtpsession; GstRtpSession *rtpsession;
GstElementClass *klass; GstElementClass *klass;

View File

@ -95,9 +95,8 @@ enum
LAST_SIGNAL LAST_SIGNAL
}; };
GST_BOILERPLATE (GstRtpSsrcDemux, gst_rtp_ssrc_demux, GstElement, #define gst_rtp_ssrc_demux_parent_class parent_class
GST_TYPE_ELEMENT); G_DEFINE_TYPE (GstRtpSsrcDemux, gst_rtp_ssrc_demux, GST_TYPE_ELEMENT);
/* GObject vmethods */ /* GObject vmethods */
static void gst_rtp_ssrc_demux_dispose (GObject * object); 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; GstPadTemplate *templ;
gchar *padname; gchar *padname;
GstRtpSsrcDemuxPad *demuxpad; GstRtpSsrcDemuxPad *demuxpad;
GstCaps *caps;
GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc); 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); demux->srcpads = g_slist_prepend (demux->srcpads, demuxpad);
/* copy caps from input */ /* 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_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_use_fixed_caps (rtcp_pad);
gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event); 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; 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 <wim.taymans@gmail.com>");
}
static void static void
gst_rtp_ssrc_demux_class_init (GstRtpSsrcDemuxClass * klass) gst_rtp_ssrc_demux_class_init (GstRtpSsrcDemuxClass * klass)
{ {
@ -307,13 +291,26 @@ gst_rtp_ssrc_demux_class_init (GstRtpSsrcDemuxClass * klass)
gstrtpssrcdemux_klass->clear_ssrc = gstrtpssrcdemux_klass->clear_ssrc =
GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_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 <wim.taymans@gmail.com>");
GST_DEBUG_CATEGORY_INIT (gst_rtp_ssrc_demux_debug, GST_DEBUG_CATEGORY_INIT (gst_rtp_ssrc_demux_debug,
"rtpssrcdemux", 0, "RTP SSRC demuxer"); "rtpssrcdemux", 0, "RTP SSRC demuxer");
} }
static void static void
gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux, gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux)
GstRtpSsrcDemuxClass * g_class)
{ {
GstElementClass *klass = GST_ELEMENT_GET_CLASS (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)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_STOP: case GST_EVENT_FLUSH_STOP:
gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED); gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
case GST_EVENT_NEWSEGMENT:
default: default:
{ {
GSList *walk; 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)); demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT:
default: default:
{ {
GSList *walk; GSList *walk;
@ -518,13 +513,16 @@ gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf)
GstRtpSsrcDemux *demux; GstRtpSsrcDemux *demux;
guint32 ssrc; guint32 ssrc;
GstRtpSsrcDemuxPad *dpad; GstRtpSsrcDemuxPad *dpad;
GstRTPBuffer rtp;
demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad)); demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad));
if (!gst_rtp_buffer_validate (buf)) if (!gst_rtp_buffer_validate (buf))
goto invalid_payload; 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); 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; guint32 ssrc;
GstRtpSsrcDemuxPad *dpad; GstRtpSsrcDemuxPad *dpad;
GstRTCPPacket packet; GstRTCPPacket packet;
GstRTCPBuffer rtcp;
demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad)); demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad));
if (!gst_rtcp_buffer_validate (buf)) if (!gst_rtcp_buffer_validate (buf))
goto invalid_rtcp; 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; goto invalid_rtcp;
}
/* first packet must be SR or RR or else the validate would have failed */ /* first packet must be SR or RR or else the validate would have failed */
switch (gst_rtcp_packet_get_type (&packet)) { switch (gst_rtcp_packet_get_type (&packet)) {
@ -582,6 +584,7 @@ gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf)
default: default:
goto unexpected_rtcp; goto unexpected_rtcp;
} }
gst_rtcp_buffer_unmap (&rtcp);
GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc); 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; GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) walk->data;
if (dpad->rtp_pad == pad || dpad->rtcp_pad == pad) { if (dpad->rtp_pad == pad || dpad->rtcp_pad == pad) {
GstStructure *ws;
event = event =
GST_EVENT_CAST (gst_mini_object_make_writable GST_EVENT_CAST (gst_mini_object_make_writable
(GST_MINI_OBJECT_CAST (event))); (GST_MINI_OBJECT_CAST (event)));
gst_structure_set (event->structure, "ssrc", G_TYPE_UINT, ws = gst_event_writable_structure (event);
dpad->ssrc, NULL); gst_structure_set (ws, "ssrc", G_TYPE_UINT, dpad->ssrc, NULL);
break; break;
} }
} }
@ -683,8 +688,15 @@ gst_rtp_ssrc_demux_iterate_internal_links_src (GstPad * pad)
break; break;
} }
} }
it = gst_iterator_new_single (GST_TYPE_PAD, otherpad, if (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);
}
GST_PAD_UNLOCK (demux); GST_PAD_UNLOCK (demux);
gst_object_unref (demux); gst_object_unref (demux);

View File

@ -608,18 +608,24 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf,
GList *list; GList *list;
guint32 rtptime; guint32 rtptime;
guint16 seqnum; guint16 seqnum;
GstRTPBuffer rtp;
g_return_val_if_fail (jbuf != NULL, FALSE); g_return_val_if_fail (jbuf != NULL, FALSE);
g_return_val_if_fail (buf != 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 */ /* loop the list to skip strictly smaller seqnum buffers */
for (list = jbuf->packets->head; list; list = g_list_next (list)) { for (list = jbuf->packets->head; list; list = g_list_next (list)) {
guint16 qseq; guint16 qseq;
gint gap; 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 */ /* compare the new seqnum to the one in the buffer */
gap = gst_rtp_buffer_compare_seqnum (seqnum, qseq); gap = gst_rtp_buffer_compare_seqnum (seqnum, qseq);
@ -633,7 +639,7 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf,
break; break;
} }
rtptime = gst_rtp_buffer_get_timestamp (buf); rtptime = gst_rtp_buffer_get_timestamp (&rtp);
switch (jbuf->mode) { switch (jbuf->mode) {
case RTP_JITTER_BUFFER_MODE_NONE: case RTP_JITTER_BUFFER_MODE_NONE:
case RTP_JITTER_BUFFER_MODE_BUFFER: case RTP_JITTER_BUFFER_MODE_BUFFER:
@ -673,11 +679,14 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf,
if (G_LIKELY (tail)) if (G_LIKELY (tail))
*tail = (list == NULL); *tail = (list == NULL);
gst_rtp_buffer_unmap (&rtp);
return TRUE; return TRUE;
/* ERRORS */ /* ERRORS */
duplicate: duplicate:
{ {
gst_rtp_buffer_unmap (&rtp);
GST_WARNING ("duplicate packet %d found", (gint) seqnum); GST_WARNING ("duplicate packet %d found", (gint) seqnum);
return FALSE; return FALSE;
} }
@ -834,6 +843,7 @@ rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer * jbuf)
guint64 high_ts, low_ts; guint64 high_ts, low_ts;
GstBuffer *high_buf, *low_buf; GstBuffer *high_buf, *low_buf;
guint32 result; guint32 result;
GstRTPBuffer rtp;
g_return_val_if_fail (jbuf != NULL, 0); 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) if (!high_buf || !low_buf || high_buf == low_buf)
return 0; return 0;
high_ts = gst_rtp_buffer_get_timestamp (high_buf); gst_rtp_buffer_map (high_buf, GST_MAP_READ, &rtp);
low_ts = gst_rtp_buffer_get_timestamp (low_buf); 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 */ /* it needs to work if ts wraps */
if (high_ts >= low_ts) { if (high_ts >= low_ts) {

View File

@ -158,7 +158,7 @@ gst_rtp_bin_marshal_BOOLEAN__MINIOBJECT_BOOLEAN (GClosure * closure,
cc->callback); cc->callback);
v_return = callback (data1, 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_get_boolean (param_values + 2), data2);
g_value_set_boolean (return_value, v_return); 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 + 2),
g_value_get_uint (param_values + 3), g_value_get_uint (param_values + 3),
g_value_get_uint (param_values + 4), 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) GstClockTime running_time, guint64 ntpnstime)
{ {
GstMetaNetAddress *meta; GstMetaNetAddress *meta;
GstRTPBuffer rtpb;
/* get time of arrival */ /* get time of arrival */
arrival->current_time = current_time; arrival->current_time = current_time;
@ -1677,10 +1678,12 @@ update_arrival_stats (RTPSession * sess, RTPArrivalStats * arrival,
arrival->ntpnstime = ntpnstime; arrival->ntpnstime = ntpnstime;
/* get packet size including header overhead */ /* 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) { 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 { } else {
arrival->payload_len = 0; arrival->payload_len = 0;
} }
@ -1720,6 +1723,7 @@ rtp_session_process_rtp (RTPSession * sess, GstBuffer * buffer,
guint32 csrcs[16]; guint32 csrcs[16];
guint8 i, count; guint8 i, count;
guint64 oldrate; guint64 oldrate;
GstRTPBuffer rtp;
g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER (buffer), 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; goto ignore;
/* get SSRC and look up in session database */ /* 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); source = obtain_source (sess, ssrc, &created, &arrival, TRUE);
if (!source) if (!source) {
gst_rtp_buffer_unmap (&rtp);
goto collision; goto collision;
}
prevsender = RTP_SOURCE_IS_SENDER (source);
prevactive = RTP_SOURCE_IS_ACTIVE (source);
oldrate = source->bitrate;
/* copy available csrc for later */ /* 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 /* make sure to not overflow our array. An RTP buffer can maximally contain
* 16 CSRCs */ * 16 CSRCs */
count = MIN (count, 16); count = MIN (count, 16);
for (i = 0; i < count; i++) 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 */ /* let source process the packet */
result = rtp_source_process_rtp (source, buffer, &arrival); result = rtp_source_process_rtp (source, buffer, &arrival);
@ -2191,8 +2200,8 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet,
GstBuffer *fci_buffer = NULL; GstBuffer *fci_buffer = NULL;
if (fci_length > 0) { if (fci_length > 0) {
fci_buffer = gst_buffer_create_sub (packet->buffer, fci_buffer = gst_buffer_copy_region (packet->rtcp->buffer,
fci_data - GST_BUFFER_DATA (packet->buffer), fci_length); GST_BUFFER_COPY_MEMORY, fci_data - packet->rtcp->data, fci_length);
GST_BUFFER_TIMESTAMP (fci_buffer) = arrival->running_time; 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; gboolean more, is_bye = FALSE, do_sync = FALSE;
RTPArrivalStats arrival; RTPArrivalStats arrival;
GstFlowReturn result = GST_FLOW_OK; GstFlowReturn result = GST_FLOW_OK;
GstRTCPBuffer rtcp;
g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER (buffer), 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; goto ignore;
/* start processing the compound packet */ /* 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) { while (more) {
GstRTCPType type; GstRTCPType type;
@ -2313,6 +2324,8 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer,
more = gst_rtcp_packet_move_to_next (&packet); 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 /* if we are scheduling a BYE, we only want to count bye packets, else we
* count everything */ * count everything */
if (sess->source->received_bye) { 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 */ /* notify caller of sr packets in the callback */
if (do_sync && sess->callbacks.sync_rtcp) { if (do_sync && sess->callbacks.sync_rtcp) {
/* make writable, we might want to change the buffer */ /* 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, result = sess->callbacks.sync_rtcp (sess, sess->source, buffer,
sess->sync_rtcp_user_data); 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); g_return_val_if_fail (is_list || GST_IS_BUFFER (data), GST_FLOW_ERROR);
if (is_list) { 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 { } else {
valid_packet = gst_rtp_buffer_validate (GST_BUFFER_CAST (data)); 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; GstRTCPPacket *packet = &data->packet;
RTPSource *own = sess->source; RTPSource *own = sess->source;
GstRTCPBuffer rtcp;
data->rtcp = gst_rtcp_buffer_new (sess->mtu); data->rtcp = gst_rtcp_buffer_new (sess->mtu);
gst_rtcp_buffer_map (data->rtcp, GST_MAP_WRITE, &rtcp);
if (RTP_SOURCE_IS_SENDER (own)) { if (RTP_SOURCE_IS_SENDER (own)) {
guint64 ntptime; guint64 ntptime;
guint32 rtptime; guint32 rtptime;
@ -2651,7 +2672,7 @@ session_start_rtcp (RTPSession * sess, ReportData * data)
/* we are a sender, create SR */ /* we are a sender, create SR */
GST_DEBUG ("create SR for SSRC %08x", own->ssrc); 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 */ /* get latest stats */
rtp_source_get_new_sr (own, data->ntpnstime, data->running_time, rtp_source_get_new_sr (own, data->ntpnstime, data->running_time,
@ -2666,9 +2687,11 @@ session_start_rtcp (RTPSession * sess, ReportData * data)
} else { } else {
/* we are only receiver, create RR */ /* we are only receiver, create RR */
GST_DEBUG ("create RR for SSRC %08x", own->ssrc); 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_packet_rr_set_ssrc (packet, own->ssrc);
} }
gst_rtcp_buffer_unmap (&rtcp);
} }
/* construct a Sender or Receiver Report */ /* construct a Sender or Receiver Report */
@ -2792,9 +2815,12 @@ session_sdes (RTPSession * sess, ReportData * data)
GstRTCPPacket *packet = &data->packet; GstRTCPPacket *packet = &data->packet;
const GstStructure *sdes; const GstStructure *sdes;
gint i, n_fields; gint i, n_fields;
GstRTCPBuffer rtcp;
gst_rtcp_buffer_map (data->rtcp, GST_MAP_WRITE, &rtcp);
/* add SDES packet */ /* 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); gst_rtcp_packet_sdes_add_item (packet, sess->source->ssrc);
@ -2848,6 +2874,8 @@ session_sdes (RTPSession * sess, ReportData * data)
} }
data->has_sdes = TRUE; data->has_sdes = TRUE;
gst_rtcp_buffer_unmap (&rtcp);
} }
/* schedule a BYE packet */ /* schedule a BYE packet */
@ -2855,6 +2883,7 @@ static void
session_bye (RTPSession * sess, ReportData * data) session_bye (RTPSession * sess, ReportData * data)
{ {
GstRTCPPacket *packet = &data->packet; GstRTCPPacket *packet = &data->packet;
GstRTCPBuffer rtcp;
/* open packet */ /* open packet */
session_start_rtcp (sess, data); session_start_rtcp (sess, data);
@ -2862,14 +2891,18 @@ session_bye (RTPSession * sess, ReportData * data)
/* add SDES */ /* add SDES */
session_sdes (sess, data); session_sdes (sess, data);
gst_rtcp_buffer_map (data->rtcp, GST_MAP_WRITE, &rtcp);
/* add a BYE packet */ /* 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); gst_rtcp_packet_bye_add_ssrc (packet, sess->source->ssrc);
if (sess->bye_reason) if (sess->bye_reason)
gst_rtcp_packet_bye_set_reason (packet, sess->bye_reason); gst_rtcp_packet_bye_set_reason (packet, sess->bye_reason);
/* we have a BYE packet now */ /* we have a BYE packet now */
data->is_bye = TRUE; data->is_bye = TRUE;
gst_rtcp_buffer_unmap (&rtcp);
} }
static gboolean 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)) { if (sess->callbacks.send_rtcp && (do_not_suppress || !data.may_suppress)) {
guint packet_size; guint packet_size;
/* close the RTCP packet */ packet_size = gst_buffer_get_size (data.rtcp) + sess->header_len;
gst_rtcp_buffer_end (data.rtcp);
packet_size = GST_BUFFER_SIZE (data.rtcp) + sess->header_len;
UPDATE_AVG (sess->stats.avg_rtcp_packet_size, packet_size); UPDATE_AVG (sess->stats.avg_rtcp_packet_size, packet_size);
GST_DEBUG ("%p, sending RTCP packet, avg size %u, %u", &sess->stats, 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) has_pli_compare_func (gconstpointer a, gconstpointer ignored)
{ {
GstRTCPPacket packet; GstRTCPPacket packet;
GstRTCPBuffer rtcp;
gboolean ret = FALSE;
packet.buffer = (GstBuffer *) a; gst_rtcp_buffer_map ((GstBuffer *) a, GST_MAP_READ, &rtcp);
packet.offset = 0;
if (gst_rtcp_packet_get_type (&packet) == GST_RTCP_TYPE_PSFB && if (gst_rtcp_buffer_get_first_packet (&rtcp, &packet)) {
gst_rtcp_packet_fb_get_type (&packet) == GST_RTCP_PSFB_TYPE_PLI) if (gst_rtcp_packet_get_type (&packet) == GST_RTCP_TYPE_PSFB &&
return TRUE; gst_rtcp_packet_fb_get_type (&packet) == GST_RTCP_PSFB_TYPE_PLI)
else ret = TRUE;
return FALSE; }
gst_rtcp_buffer_unmap (&rtcp);
return ret;
} }
static gboolean static gboolean
@ -3216,16 +3251,21 @@ rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer,
if (media_src && !rtp_source_has_retained (media_src, if (media_src && !rtp_source_has_retained (media_src,
has_pli_compare_func, NULL)) { 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_type (&rtcppacket, GST_RTCP_PSFB_TYPE_PLI);
gst_rtcp_packet_fb_set_sender_ssrc (&rtcppacket, gst_rtcp_packet_fb_set_sender_ssrc (&rtcppacket,
rtp_source_get_ssrc (sess->source)); rtp_source_get_ssrc (sess->source));
gst_rtcp_packet_fb_set_media_ssrc (&rtcppacket, media_ssrc); gst_rtcp_packet_fb_set_media_ssrc (&rtcppacket, media_ssrc);
ret = TRUE; ret = TRUE;
gst_rtcp_buffer_unmap (&rtcp);
} else { } else {
/* Break because the packet is full, will put next request in a /* Break because the packet is full, will put next request in a
* further packet * further packet
*/ */
gst_rtcp_buffer_unmap (&rtcp);
break; break;
} }
} }

View File

@ -897,20 +897,24 @@ calculate_jitter (RTPSource * src, GstBuffer * buffer,
gint32 diff; gint32 diff;
gint clock_rate; gint clock_rate;
guint8 pt; guint8 pt;
GstRTPBuffer rtp;
/* get arrival time */ /* get arrival time */
if ((running_time = arrival->running_time) == GST_CLOCK_TIME_NONE) if ((running_time = arrival->running_time) == GST_CLOCK_TIME_NONE)
goto no_time; 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); GST_LOG ("SSRC %08x got payload %d", src->ssrc, pt);
/* get clockrate */ /* 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; 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 /* convert arrival time to RTP timestamp units, truncate to 32 bits, we don't
* care about the absolute value, just the difference. */ * 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", GST_LOG ("rtparrival %u, rtptime %u, clock-rate %d, diff %d, jitter: %f",
rtparrival, rtptime, clock_rate, diff, (src->stats.jitter) / 16.0); rtparrival, rtptime, clock_rate, diff, (src->stats.jitter) / 16.0);
gst_rtp_buffer_unmap (&rtp);
return; return;
/* ERRORS */ /* ERRORS */
@ -1021,15 +1026,21 @@ rtp_source_process_rtp (RTPSource * src, GstBuffer * buffer,
guint16 seqnr, udelta; guint16 seqnr, udelta;
RTPSourceStats *stats; RTPSourceStats *stats;
guint16 expected; guint16 expected;
GstRTPBuffer rtp;
g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR); g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
stats = &src->stats; 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) { if (stats->cycles == -1) {
GST_DEBUG ("received first buffer"); GST_DEBUG ("received first buffer");
@ -1157,12 +1168,16 @@ rtp_source_process_bye (RTPSource * src, const gchar * reason)
src->received_bye = TRUE; src->received_bye = TRUE;
} }
static GstBufferListItem static gboolean
set_ssrc (GstBuffer ** buffer, guint group, guint idx, RTPSource * src) set_ssrc (GstBuffer ** buffer, guint idx, RTPSource * src)
{ {
GstRTPBuffer rtp;
*buffer = gst_buffer_make_writable (*buffer); *buffer = gst_buffer_make_writable (*buffer);
gst_rtp_buffer_set_ssrc (*buffer, src->ssrc); gst_rtp_buffer_map (*buffer, GST_MAP_WRITE, &rtp);
return GST_BUFFER_LIST_SKIP_GROUP; 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; GstBuffer *buffer = NULL;
guint packets; guint packets;
guint32 ssrc; guint32 ssrc;
GstRTPBuffer rtp;
g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR); 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); 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 /* We can grab the caps from the first group, since all
* groups of a buffer list have same caps. */ * 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) if (!buffer)
goto no_buffer; goto no_buffer;
} else { } else {
buffer = GST_BUFFER_CAST (data); 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 */ /* we are a sender now */
src->is_sender = TRUE; src->is_sender = TRUE;
if (is_list) { if (is_list) {
gint i;
/* Each group makes up a network packet. */ /* Each group makes up a network packet. */
packets = gst_buffer_list_n_groups (list); packets = gst_buffer_list_len (list);
len = gst_rtp_buffer_list_get_payload_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 { } else {
packets = 1; 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 */ /* 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); do_bitrate_estimation (src, running_time, &src->bytes_sent);
if (is_list) { rtptime = gst_rtp_buffer_get_timestamp (&rtp);
rtptime = gst_rtp_buffer_list_get_timestamp (list);
} else {
rtptime = gst_rtp_buffer_get_timestamp (buffer);
}
ext_rtptime = src->last_rtptime; ext_rtptime = src->last_rtptime;
ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, 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; src->last_rtptime = ext_rtptime;
/* push packet */ /* push packet */
if (!src->callbacks.push_rtp) if (!src->callbacks.push_rtp) {
gst_rtp_buffer_unmap (&rtp);
goto no_callback; 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) { if (ssrc != src->ssrc) {
/* the SSRC of the packet is not correct, make a writable buffer and /* 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 * 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); list = gst_buffer_list_make_writable (list);
gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc, src); gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc, src);
} else { } else {
set_ssrc (&buffer, 0, 0, src); set_ssrc (&buffer, 0, src);
} }
} }
GST_LOG ("pushing RTP %s %" G_GUINT64_FORMAT, is_list ? "list" : "packet", 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; GstBuffer *buffer;
buffer = gst_buffer_create_sub (packet->buffer, packet->offset, buffer = gst_buffer_copy_region (packet->rtcp->buffer, GST_BUFFER_COPY_MEMORY,
(gst_rtcp_packet_get_length (packet) + 1) * 4); packet->offset, (gst_rtcp_packet_get_length (packet) + 1) * 4);
GST_BUFFER_TIMESTAMP (buffer) = running_time; GST_BUFFER_TIMESTAMP (buffer) = running_time;