#include <gst/rtp/gstrtpbuffer.h>
#include <gst/rtp/gstrtcpbuffer.h>
-#include <gst/netbuffer/gstnetbuffer.h>
#include <gst/glib-compat-private.h>
}
static void
-gst_rtp_bin_marshal_BOOLEAN__MINIOBJECT_BOOLEAN (GClosure * closure,
- GValue * return_value G_GNUC_UNUSED, guint n_param_values,
- const GValue * param_values, gpointer invocation_hint G_GNUC_UNUSED,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__MINIOBJECT_BOOLEAN) (gpointer data1,
- gpointer arg_1, gboolean arg_2, gpointer data2);
- register GMarshalFunc_BOOLEAN__MINIOBJECT_BOOLEAN callback;
- register GCClosure *cc = (GCClosure *) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure)) {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- } else {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback =
- (GMarshalFunc_BOOLEAN__MINIOBJECT_BOOLEAN) (marshal_data ? marshal_data :
- cc->callback);
-
- v_return = callback (data1,
- gst_value_get_mini_object (param_values + 1),
- g_value_get_boolean (param_values + 2), data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-static void
-gst_rtp_bin_marshal_VOID__UINT_UINT_UINT_UINT_MINIOBJECT (GClosure * closure,
- GValue * return_value G_GNUC_UNUSED, guint n_param_values,
- const GValue * param_values, gpointer invocation_hint G_GNUC_UNUSED,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__UINT_UINT_UINT_UINT_MINIOBJECT) (gpointer
- data1, guint arg_1, guint arg_2, guint arg_3, guint arg_4, gpointer arg_5,
- gpointer data2);
- register GMarshalFunc_VOID__UINT_UINT_UINT_UINT_MINIOBJECT callback;
- register GCClosure *cc = (GCClosure *) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 6);
-
- if (G_CCLOSURE_SWAP_DATA (closure)) {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- } else {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback =
- (GMarshalFunc_VOID__UINT_UINT_UINT_UINT_MINIOBJECT) (marshal_data ?
- marshal_data : cc->callback);
-
- callback (data1,
- g_value_get_uint (param_values + 1),
- 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);
-}
-
-
-static void
rtp_session_class_init (RTPSessionClass * klass)
{
GObjectClass *gobject_class;
rtp_session_signals[SIGNAL_ON_SENDING_RTCP] =
g_signal_new ("on-sending-rtcp", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_sending_rtcp),
- accumulate_trues, NULL, gst_rtp_bin_marshal_BOOLEAN__MINIOBJECT_BOOLEAN,
- G_TYPE_BOOLEAN, 2, GST_TYPE_BUFFER, G_TYPE_BOOLEAN);
+ accumulate_trues, NULL, gst_rtp_bin_marshal_BOOLEAN__BOXED_BOOLEAN,
+ G_TYPE_BOOLEAN, 2, GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_BOOLEAN);
/**
* RTPSession::on-feedback-rtcp:
*
* Notify that a RTCP feedback packet has been received
*/
-
rtp_session_signals[SIGNAL_ON_FEEDBACK_RTCP] =
g_signal_new ("on-feedback-rtcp", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_feedback_rtcp),
- NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT_UINT_UINT_MINIOBJECT,
+ NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT_UINT_UINT_BOXED,
G_TYPE_NONE, 5, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT,
GST_TYPE_BUFFER);
gint i;
gchar *str;
- sess->lock = g_mutex_new ();
+ g_mutex_init (&sess->lock);
sess->key = g_random_int ();
sess->mask_idx = 0;
sess->mask = 0;
sess = RTP_SESSION_CAST (object);
- g_mutex_free (sess->lock);
+ g_mutex_clear (&sess->lock);
for (i = 0; i < 32; i++)
g_hash_table_destroy (sess->ssrcs[i]);
RTPArrivalStats * arrival, gboolean rtp)
{
/* If we have no arrival address, we can't do collision checking */
- if (!arrival->have_address)
+ if (!arrival->address)
return FALSE;
if (sess->source != source) {
- GstNetAddress *from;
- gboolean have_from;
+ GSocketAddress *from;
/* This is not our local source, but lets check if two remote
* source collide
*/
if (rtp) {
- from = &source->rtp_from;
- have_from = source->have_rtp_from;
+ from = source->rtp_from;
} else {
- from = &source->rtcp_from;
- have_from = source->have_rtcp_from;
+ from = source->rtcp_from;
}
- if (have_from) {
- if (gst_netaddress_equal (from, &arrival->address)) {
+ if (from) {
+ if (__g_socket_address_equal (from, arrival->address)) {
/* Address is the same */
return FALSE;
} else {
rtp_source_get_ssrc (source));
if (sess->favor_new) {
if (rtp_source_find_conflicting_address (source,
- &arrival->address, arrival->current_time)) {
- gchar buf1[40];
- gst_netaddress_to_string (&arrival->address, buf1, 40);
+ arrival->address, arrival->current_time)) {
+ gchar *buf1;
+
+ buf1 = __g_socket_address_to_string (arrival->address);
GST_LOG ("Known conflict on %x for %s, dropping packet",
rtp_source_get_ssrc (source), buf1);
+ g_free (buf1);
+
return TRUE;
} else {
- gchar buf1[40], buf2[40];
+ gchar *buf1, *buf2;
/* Current address is not a known conflict, lets assume this is
* a new source. Save old address in possible conflict list
rtp_source_add_conflicting_address (source, from,
arrival->current_time);
- gst_netaddress_to_string (from, buf1, 40);
- gst_netaddress_to_string (&arrival->address, buf2, 40);
+ buf1 = __g_socket_address_to_string (from);
+ buf2 = __g_socket_address_to_string (arrival->address);
+
GST_DEBUG ("New conflict for ssrc %x, replacing %s with %s,"
" saving old as known conflict",
rtp_source_get_ssrc (source), buf1, buf2);
if (rtp)
- rtp_source_set_rtp_from (source, &arrival->address);
+ rtp_source_set_rtp_from (source, arrival->address);
else
- rtp_source_set_rtcp_from (source, &arrival->address);
+ rtp_source_set_rtcp_from (source, arrival->address);
+
+ g_free (buf1);
+ g_free (buf2);
+
return FALSE;
}
} else {
} else {
/* We don't already have a from address for RTP, just set it */
if (rtp)
- rtp_source_set_rtp_from (source, &arrival->address);
+ rtp_source_set_rtp_from (source, arrival->address);
else
- rtp_source_set_rtcp_from (source, &arrival->address);
+ rtp_source_set_rtcp_from (source, arrival->address);
return FALSE;
}
if (inactivity_period > 1 * GST_SECOND) {
/* Use new network address */
if (rtp) {
- g_assert (source->have_rtp_from);
- rtp_source_set_rtp_from (source, &arrival->address);
+ g_assert (source->rtp_from);
+ rtp_source_set_rtp_from (source, arrival->address);
} else {
- g_assert (source->have_rtcp_from);
- rtp_source_set_rtcp_from (source, &arrival->address);
+ g_assert (source->rtcp_from);
+ rtp_source_set_rtcp_from (source, arrival->address);
}
return FALSE;
}
} else {
/* This is sending with our ssrc, is it an address we already know */
- if (rtp_source_find_conflicting_address (source, &arrival->address,
+ if (rtp_source_find_conflicting_address (source, arrival->address,
arrival->current_time)) {
/* Its a known conflict, its probably a loop, not a collision
* lets just drop the incoming packet
} else {
/* Its a new collision, lets change our SSRC */
- rtp_source_add_conflicting_address (source, &arrival->address,
+ rtp_source_add_conflicting_address (source, arrival->address,
arrival->current_time);
GST_DEBUG ("Collision for SSRC %x", rtp_source_get_ssrc (source));
source->probation = 0;
/* store from address, if any */
- if (arrival->have_address) {
+ if (arrival->address) {
if (rtp)
- rtp_source_set_rtp_from (source, &arrival->address);
+ rtp_source_set_rtp_from (source, arrival->address);
else
- rtp_source_set_rtcp_from (source, &arrival->address);
+ rtp_source_set_rtcp_from (source, arrival->address);
}
/* configure a callback on the source */
gboolean rtp, GstBuffer * buffer, GstClockTime current_time,
GstClockTime running_time, guint64 ntpnstime)
{
+ GstNetAddressMeta *meta;
+ GstRTPBuffer rtpb = { NULL };
+
/* get time of arrival */
arrival->current_time = current_time;
arrival->running_time = running_time;
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;
}
/* for netbuffer we can store the IP address to check for collisions */
- arrival->have_address = GST_IS_NETBUFFER (buffer);
- if (arrival->have_address) {
- GstNetBuffer *netbuf = (GstNetBuffer *) buffer;
-
- memcpy (&arrival->address, &netbuf->from, sizeof (GstNetAddress));
+ meta = gst_buffer_get_net_address_meta (buffer);
+ if (arrival->address)
+ g_object_unref (arrival->address);
+ if (meta) {
+ arrival->address = G_SOCKET_ADDRESS (g_object_ref (meta->addr));
+ } else {
+ arrival->address = NULL;
}
}
RTPSource *source;
gboolean created;
gboolean prevsender, prevactive;
- RTPArrivalStats arrival;
+ RTPArrivalStats arrival = { NULL, };
guint32 csrcs[16];
guint8 i, count;
guint64 oldrate;
+ GstRTPBuffer rtp = { NULL };
g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
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);
if (!source)
return;
- sdes = gst_structure_new ("application/x-rtp-source-sdes", NULL);
+ sdes = gst_structure_new_empty ("application/x-rtp-source-sdes");
more_entries = gst_rtcp_packet_sdes_first_entry (packet);
j = 0;
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->map.data,
+ fci_length);
GST_BUFFER_TIMESTAMP (fci_buffer) = arrival->running_time;
}
{
GstRTCPPacket packet;
gboolean more, is_bye = FALSE, do_sync = FALSE;
- RTPArrivalStats arrival;
+ RTPArrivalStats arrival = { NULL, };
GstFlowReturn result = GST_FLOW_OK;
+ GstRTCPBuffer rtcp = { NULL, };
g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
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;
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) {
sess->stats.avg_rtcp_packet_size, arrival.bytes);
RTP_SESSION_UNLOCK (sess);
+ if (arrival.address)
+ g_object_unref (arrival.address);
+
/* 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);
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_length (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));
}
typedef struct
{
+ GstRTCPBuffer rtcpbuf;
RTPSession *sess;
GstBuffer *rtcp;
GstClockTime current_time;
{
GstRTCPPacket *packet = &data->packet;
RTPSource *own = sess->source;
+ GstRTCPBuffer *rtcp = &data->rtcpbuf;
data->rtcp = gst_rtcp_buffer_new (sess->mtu);
+ gst_rtcp_buffer_map (data->rtcp, GST_MAP_READWRITE, rtcp);
+
if (RTP_SOURCE_IS_SENDER (own)) {
guint64 ntptime;
guint32 rtptime;
/* 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,
} 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);
}
}
GstRTCPPacket *packet = &data->packet;
const GstStructure *sdes;
gint i, n_fields;
+ GstRTCPBuffer *rtcp = &data->rtcpbuf;
/* 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);
session_bye (RTPSession * sess, ReportData * data)
{
GstRTCPPacket *packet = &data->packet;
+ GstRTCPBuffer *rtcp = &data->rtcpbuf;
/* open packet */
session_start_rtcp (sess, data);
session_sdes (sess, data);
/* 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);
guint64 ntpnstime, GstClockTime running_time)
{
GstFlowReturn result = GST_FLOW_OK;
- ReportData data;
+ ReportData data = { GST_RTCP_BUFFER_INIT };
RTPSource *own;
GHashTable *table_copy;
gboolean notify = FALSE;
if (data.rtcp) {
gboolean do_not_suppress;
+ gst_rtcp_buffer_unmap (&data.rtcpbuf);
+
/* Give the user a change to add its own packet */
g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SENDING_RTCP], 0,
data.rtcp, data.is_early, &do_not_suppress);
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,
has_pli_compare_func (gconstpointer a, gconstpointer ignored)
{
GstRTCPPacket packet;
+ GstRTCPBuffer rtcp = { NULL, };
+ 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
gpointer key, value;
gboolean started_fir = FALSE;
GstRTCPPacket fir_rtcppacket;
+ GstRTCPBuffer rtcp = { NULL, };
RTP_SESSION_LOCK (sess);
+ gst_rtcp_buffer_map (buffer, GST_MAP_READWRITE, &rtcp);
+
g_hash_table_iter_init (&iter, sess->ssrcs[sess->mask_idx]);
while (g_hash_table_iter_next (&iter, &key, &value)) {
guint media_ssrc = GPOINTER_TO_UINT (key);
if (media_src->send_fir) {
if (!started_fir) {
- if (!gst_rtcp_buffer_add_packet (buffer, GST_RTCP_TYPE_PSFB,
+ if (!gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_PSFB,
&fir_rtcppacket))
break;
gst_rtcp_packet_fb_set_type (&fir_rtcppacket, GST_RTCP_PSFB_TYPE_FIR);
if (media_src->send_pli && !rtp_source_has_retained (media_src,
has_pli_compare_func, NULL)) {
- if (gst_rtcp_buffer_add_packet (buffer, GST_RTCP_TYPE_PSFB,
- &pli_rtcppacket)) {
- gst_rtcp_packet_fb_set_type (&pli_rtcppacket, GST_RTCP_PSFB_TYPE_PLI);
- gst_rtcp_packet_fb_set_sender_ssrc (&pli_rtcppacket,
- rtp_source_get_ssrc (sess->source));
- gst_rtcp_packet_fb_set_media_ssrc (&pli_rtcppacket, media_ssrc);
- ret = TRUE;
- } else {
+ if (!gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_PSFB,
+ &pli_rtcppacket))
/* Break because the packet is full, will put next request in a
- * further packet
- */
+ * further packet */
break;
- }
+ gst_rtcp_packet_fb_set_type (&pli_rtcppacket, GST_RTCP_PSFB_TYPE_PLI);
+ gst_rtcp_packet_fb_set_sender_ssrc (&pli_rtcppacket,
+ rtp_source_get_ssrc (sess->source));
+ gst_rtcp_packet_fb_set_media_ssrc (&pli_rtcppacket, media_ssrc);
+ ret = TRUE;
}
media_src->send_pli = FALSE;
}
+ gst_rtcp_buffer_unmap (&rtcp);
RTP_SESSION_UNLOCK (sess);