Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst / rtpmanager / rtpsession.c
index 24e752b..9537840 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <gst/rtp/gstrtpbuffer.h>
 #include <gst/rtp/gstrtcpbuffer.h>
-#include <gst/netbuffer/gstnetbuffer.h>
 
 #include <gst/glib-compat-private.h>
 
@@ -139,75 +138,6 @@ accumulate_trues (GSignalInvocationHint * ihint, GValue * return_accu,
 }
 
 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;
@@ -355,8 +285,9 @@ rtp_session_class_init (RTPSessionClass * klass)
   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:
@@ -371,11 +302,10 @@ rtp_session_class_init (RTPSessionClass * klass)
    *
    * 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);
 
@@ -523,7 +453,7 @@ rtp_session_init (RTPSession * sess)
   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;
@@ -594,7 +524,7 @@ rtp_session_finalize (GObject * object)
 
   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]);
 
@@ -1270,27 +1200,24 @@ check_collision (RTPSession * sess, RTPSource * source,
     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 {
@@ -1298,14 +1225,17 @@ check_collision (RTPSession * sess, RTPSource * source,
             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
@@ -1313,16 +1243,21 @@ check_collision (RTPSession * sess, RTPSource * source,
             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 {
@@ -1333,9 +1268,9 @@ check_collision (RTPSession * sess, RTPSource * source,
     } 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;
     }
 
@@ -1353,11 +1288,11 @@ check_collision (RTPSession * sess, RTPSource * source,
       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;
       }
@@ -1365,7 +1300,7 @@ check_collision (RTPSession * sess, RTPSource * source,
   } 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
@@ -1374,7 +1309,7 @@ check_collision (RTPSession * sess, RTPSource * source,
     } 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));
@@ -1414,11 +1349,11 @@ obtain_source (RTPSession * sess, guint32 ssrc, gboolean * created,
       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 */
@@ -1709,26 +1644,33 @@ update_arrival_stats (RTPSession * sess, RTPArrivalStats * arrival,
     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;
   }
 }
 
@@ -1753,10 +1695,11 @@ rtp_session_process_rtp (RTPSession * sess, GstBuffer * buffer,
   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);
@@ -1774,23 +1717,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);
@@ -2007,7 +1955,7 @@ rtp_session_process_sdes (RTPSession * sess, GstRTCPPacket * packet,
     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;
@@ -2295,8 +2243,9 @@ 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->map.data,
+          fci_length);
       GST_BUFFER_TIMESTAMP (fci_buffer) = arrival->running_time;
     }
 
@@ -2360,8 +2309,9 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer,
 {
   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);
@@ -2380,7 +2330,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;
 
@@ -2423,6 +2374,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) {
@@ -2438,10 +2391,13 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer,
       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);
@@ -2493,7 +2449,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_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));
   }
@@ -2733,6 +2694,7 @@ early_exit:
 
 typedef struct
 {
+  GstRTCPBuffer rtcpbuf;
   RTPSession *sess;
   GstBuffer *rtcp;
   GstClockTime current_time;
@@ -2751,9 +2713,12 @@ session_start_rtcp (RTPSession * sess, ReportData * data)
 {
   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;
@@ -2761,7 +2726,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,
@@ -2776,7 +2741,7 @@ 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);
   }
 }
@@ -2929,9 +2894,10 @@ session_sdes (RTPSession * sess, ReportData * data)
   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);
 
@@ -2992,6 +2958,7 @@ static void
 session_bye (RTPSession * sess, ReportData * data)
 {
   GstRTCPPacket *packet = &data->packet;
+  GstRTCPBuffer *rtcp = &data->rtcpbuf;
 
   /* open packet */
   session_start_rtcp (sess, data);
@@ -3000,7 +2967,7 @@ session_bye (RTPSession * sess, ReportData * 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);
@@ -3111,7 +3078,7 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
     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;
@@ -3221,6 +3188,8 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
   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);
@@ -3228,10 +3197,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,
@@ -3345,15 +3311,20 @@ static gboolean
 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
@@ -3365,9 +3336,12 @@ rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer,
   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);
@@ -3376,7 +3350,7 @@ rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer,
 
     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);
@@ -3415,22 +3389,20 @@ rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer,
 
     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);