rtp: Add support for multiple memory blocks in RTP
authorWim Taymans <wim.taymans@collabora.co.uk>
Tue, 17 Jul 2012 14:35:06 +0000 (16:35 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Tue, 17 Jul 2012 14:41:36 +0000 (16:41 +0200)
Add support RTP buffers with multiple memory blocks. We allow one block for the
header, one for the extension data, N for data and one memory block for the
padding.
Remove the validate function, we validate now when we map because we need to
parse things in order to map multiple memory blocks.

docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/rtp/README
gst-libs/gst/rtp/gstrtpbasedepayload.c
gst-libs/gst/rtp/gstrtpbasepayload.c
gst-libs/gst/rtp/gstrtpbuffer.c
gst-libs/gst/rtp/gstrtpbuffer.h
tests/check/libs/rtp.c

index 41a1d00..069c3d9 100644 (file)
@@ -1190,9 +1190,6 @@ gst_rtp_buffer_calc_header_len
 gst_rtp_buffer_calc_packet_len
 gst_rtp_buffer_calc_payload_len
 
-gst_rtp_buffer_validate
-gst_rtp_buffer_validate_data
-
 gst_rtp_buffer_set_packet_len
 gst_rtp_buffer_get_packet_len
 
index 77253b7..d49031e 100644 (file)
@@ -21,9 +21,7 @@ The RTP libraries
   duplicate GstBuffer with the same data as the previous one). The
   function will create a new RTP buffer with the given data as the whole RTP
   packet. Alternatively, gst_rtp_buffer_new_copy_data() can be used if the user
-  wishes to make a copy of the data before using it in the new RTP buffer. An
-  important function is gst_rtp_buffer_validate() that is used to verify that
-  the buffer a well formed RTP buffer.
+  wishes to make a copy of the data before using it in the new RTP buffer.
  
   It is now possible to use all the gst_rtp_buffer_get_*() or
   gst_rtp_buffer_set_*() functions to read or write the different parts of the
index 5dd5bfc..211ddee 100644 (file)
@@ -257,9 +257,7 @@ gst_rtp_base_depayload_chain (GstPad * pad, GstObject * parent, GstBuffer * in)
   if (G_UNLIKELY (!priv->negotiated))
     goto not_negotiated;
 
-  /* we must validate, it's possible that this element is plugged right after a
-   * network receiver and we don't want to operate on invalid data */
-  if (G_UNLIKELY (!gst_rtp_buffer_validate (in)))
+  if (G_UNLIKELY (!gst_rtp_buffer_map (in, GST_MAP_READ, &rtp)))
     goto invalid_buffer;
 
   if (!priv->discont)
@@ -275,7 +273,6 @@ gst_rtp_base_depayload_chain (GstPad * pad, GstObject * parent, GstBuffer * in)
   priv->dts = dts;
   priv->duration = GST_BUFFER_DURATION (in);
 
-  gst_rtp_buffer_map (in, GST_MAP_READ, &rtp);
   seqnum = gst_rtp_buffer_get_seq (&rtp);
   rtptime = gst_rtp_buffer_get_timestamp (&rtp);
   gst_rtp_buffer_unmap (&rtp);
index 36c179a..7acbd64 100644 (file)
@@ -747,7 +747,9 @@ set_headers (GstBuffer ** buffer, guint idx, gpointer user_data)
   HeaderData *data = user_data;
   GstRTPBuffer rtp = { NULL, };
 
-  gst_rtp_buffer_map (*buffer, GST_MAP_WRITE, &rtp);
+  if (!gst_rtp_buffer_map (*buffer, GST_MAP_WRITE, &rtp))
+    goto map_failed;
+
   gst_rtp_buffer_set_ssrc (&rtp, data->ssrc);
   gst_rtp_buffer_set_payload_type (&rtp, data->pt);
   gst_rtp_buffer_set_seq (&rtp, data->seqnum);
@@ -758,6 +760,12 @@ set_headers (GstBuffer ** buffer, guint idx, gpointer user_data)
   data->seqnum++;
 
   return TRUE;
+  /* ERRORS */
+map_failed:
+  {
+    GST_ERROR ("failed to map buffer %p", *buffer);
+    return FALSE;
+  }
 }
 
 /* Updates the SSRC, payload type, seqnum and timestamp of the RTP buffer
index 4a610e3..121aade 100644 (file)
@@ -283,29 +283,41 @@ gst_rtp_buffer_calc_payload_len (guint packet_len, guint8 pad_len,
       - pad_len;
 }
 
-/*
- * validate_data:
- * @data: the data to validate
- * @len: the length of @data to validate
- * @payload: the payload if @data represents the header only
- * @payload_len: the len of the payload
+/**
+ * gst_rtp_buffer_map:
+ * @buffer: a #GstBuffer
+ * @flags: #GstMapFlags
+ * @rtp: (out): a #GstRTPBuffer
  *
- * Checks if @data is a valid RTP packet.
+ * Map the contents of @buffer into @rtp.
  *
- * Returns: TRUE if @data is a valid RTP packet
+ * Returns: %TRUE if @buffer could be mapped.
  */
-static gboolean
-validate_data (guint8 * data, guint len, guint8 * payload, guint payload_len)
+gboolean
+gst_rtp_buffer_map (GstBuffer * buffer, GstMapFlags flags, GstRTPBuffer * rtp)
 {
   guint8 padding;
   guint8 csrc_count;
   guint header_len;
   guint8 version;
+  guint8 *data;
+  guint size;
+  gsize bufsize, skip;
+  guint idx, length;
 
-  g_return_val_if_fail (data != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+  g_return_val_if_fail (rtp != NULL, FALSE);
+  g_return_val_if_fail (rtp->buffer == NULL, FALSE);
+
+  /* map first memory, this should be the header */
+  if (!gst_buffer_map_range (buffer, 0, 1, &rtp->map[0], flags))
+    goto map_failed;
+
+  data = rtp->data[0] = rtp->map[0].data;
+  size = rtp->map[0].size;
 
   header_len = GST_RTP_HEADER_LEN;
-  if (G_UNLIKELY (len < header_len))
+  if (G_UNLIKELY (size < header_len))
     goto wrong_length;
 
   /* check version */
@@ -317,47 +329,79 @@ validate_data (guint8 * data, guint len, guint8 * payload, guint payload_len)
   csrc_count = (data[0] & 0x0f);
   header_len += csrc_count * sizeof (guint32);
 
+  rtp->size[0] = header_len;
+
+  bufsize = gst_buffer_get_size (buffer);
+
   /* calc extension length when present. */
   if (data[0] & 0x10) {
-    guint8 *extpos;
+    guint8 *extdata;
     guint16 extlen;
 
-    /* this points to the extension bits and header length */
-    extpos = &data[header_len];
-
-    /* skip the header and check that we have enough space */
-    header_len += 4;
-    if (G_UNLIKELY (len < header_len))
+    /* find memory for the extension bits */
+    if (!gst_buffer_find_memory (buffer, header_len, 4, &idx, &length, &skip))
       goto wrong_length;
 
+    if (!gst_buffer_map_range (buffer, idx, length, &rtp->map[1], flags))
+      goto map_failed;
+
+    extdata = rtp->data[1] = rtp->map[1].data + skip;
     /* skip id */
-    extpos += 2;
+    extdata += 2;
     /* read length as the number of 32 bits words */
-    extlen = GST_READ_UINT16_BE (extpos);
+    extlen = GST_READ_UINT16_BE (extdata);
+
+    rtp->size[1] = extlen * sizeof (guint32);
 
-    header_len += extlen * sizeof (guint32);
+    header_len += rtp->size[1];
+  } else {
+    rtp->data[1] = NULL;
+    rtp->size[1] = 0;
   }
 
   /* check for padding */
   if (data[0] & 0x20) {
-    if (payload)
-      padding = payload[payload_len - 1];
-    else
-      padding = data[len - 1];
+    /* find memory for the padding bits */
+    if (!gst_buffer_find_memory (buffer, bufsize - 1, 1, &idx, &length, &skip))
+      goto wrong_length;
+
+    if (!gst_buffer_map_range (buffer, idx, length, &rtp->map[3], flags))
+      goto map_failed;
+
+    padding = rtp->map[3].data[skip];
+    if (skip + 1 < padding)
+      goto wrong_length;
+
+    rtp->data[3] = rtp->map[3].data + skip + 1 - padding;
+    rtp->size[3] = padding;
   } else {
+    rtp->data[3] = NULL;
+    rtp->size[3] = 0;
     padding = 0;
   }
 
   /* check if padding and header not bigger than packet length */
-  if (G_UNLIKELY (len < padding + header_len))
+  if (G_UNLIKELY (bufsize < padding + header_len))
     goto wrong_padding;
 
+  rtp->buffer = buffer;
+  /* we have not yet mapped the payload */
+  rtp->data[2] = NULL;
+  rtp->size[2] = 0;
+  rtp->state = 0;
+  rtp->n_map = 1;
+
   return TRUE;
 
   /* ERRORS */
+map_failed:
+  {
+    GST_ERROR ("failed to map memory");
+    return FALSE;
+  }
 wrong_length:
   {
-    GST_DEBUG ("len < header_len check failed (%d < %d)", len, header_len);
+    GST_DEBUG ("length check failed");
     goto dump_packet;
   }
 wrong_version:
@@ -367,89 +411,37 @@ wrong_version:
   }
 wrong_padding:
   {
-    GST_DEBUG ("padding check failed (%d - %d < %d)", len, header_len, padding);
+    GST_DEBUG ("padding check failed (%d - %d < %d)", bufsize, header_len,
+        padding);
     goto dump_packet;
   }
 dump_packet:
   {
-    GST_MEMDUMP ("buffer", data, len);
+    GST_MEMDUMP ("buffer", data, size);
     return FALSE;
   }
 }
 
 /**
- * gst_rtp_buffer_validate_data:
- * @data: (array length=len) (element-type guint8): the data to
- *   validate
- * @len: the length of @data to validate
- *
- * Check if the @data and @size point to the data of a valid RTP packet.
- * This function checks the length, version and padding of the packet data.
- * Use this function to validate a packet before using the other functions in
- * this module.
- *
- * Returns: TRUE if the data points to a valid RTP packet.
- */
-gboolean
-gst_rtp_buffer_validate_data (guint8 * data, gsize len)
-{
-  return validate_data (data, len, NULL, 0);
-}
-
-/**
- * gst_rtp_buffer_validate:
- * @buffer: the buffer to validate
- *
- * Check if the data pointed to by @buffer is a valid RTP packet using
- * gst_rtp_buffer_validate_data().
- * Use this function to validate a packet before using the other functions in
- * this module.
+ * gst_rtp_buffer_unmap:
+ * @rtp: a #GstRTPBuffer
  *
- * Returns: TRUE if @buffer is a valid RTP packet.
+ * Unmap @rtp previously mapped with gst_rtp_buffer_map().
  */
-gboolean
-gst_rtp_buffer_validate (GstBuffer * buffer)
-{
-  gboolean res;
-  GstMapInfo map;
-
-  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
-
-  gst_buffer_map (buffer, &map, GST_MAP_READ);
-  res = validate_data (map.data, map.size, NULL, 0);
-  gst_buffer_unmap (buffer, &map);
-
-  return res;
-}
-
-gboolean
-gst_rtp_buffer_map (GstBuffer * buffer, GstMapFlags flags, GstRTPBuffer * rtp)
-{
-  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
-  g_return_val_if_fail (rtp != NULL, FALSE);
-  g_return_val_if_fail (rtp->buffer == NULL, FALSE);
-
-  if (!gst_buffer_map (buffer, &rtp->map[0], flags))
-    return FALSE;
-
-  rtp->buffer = buffer;
-  rtp->state = 0;
-  rtp->n_map = 1;
-
-  return TRUE;
-}
-
-gboolean
+void
 gst_rtp_buffer_unmap (GstRTPBuffer * rtp)
 {
-  g_return_val_if_fail (rtp != NULL, FALSE);
-  g_return_val_if_fail (rtp->buffer != NULL, FALSE);
+  gint i;
+
+  g_return_if_fail (rtp != NULL);
+  g_return_if_fail (rtp->buffer != NULL);
 
-  gst_buffer_unmap (rtp->buffer, &rtp->map[0]);
+  for (i = 0; i < 4; i++) {
+    if (rtp->data[i])
+      gst_buffer_unmap (rtp->buffer, &rtp->map[i]);
+  }
   rtp->buffer = NULL;
   rtp->n_map = 0;
-
-  return TRUE;
 }
 
 
@@ -466,7 +458,9 @@ gst_rtp_buffer_set_packet_len (GstRTPBuffer * rtp, guint len)
 {
   guint8 *data;
 
-  data = rtp->map[0].data;
+  data = rtp->data[0];
+
+  /* FIXME */
 
   if (rtp->map[0].maxsize <= len) {
     /* FIXME, realloc bigger space */
@@ -506,16 +500,7 @@ gst_rtp_buffer_get_packet_len (GstRTPBuffer * rtp)
 guint
 gst_rtp_buffer_get_header_len (GstRTPBuffer * rtp)
 {
-  guint len;
-  guint8 *data;
-
-  data = rtp->map[0].data;
-
-  len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
-  if (GST_RTP_HEADER_EXTENSION (data))
-    len += GST_READ_UINT16_BE (data + len + 2) * 4 + 4;
-
-  return len;
+  return rtp->size[0] + rtp->size[1];
 }
 
 /**
@@ -529,7 +514,7 @@ gst_rtp_buffer_get_header_len (GstRTPBuffer * rtp)
 guint8
 gst_rtp_buffer_get_version (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_VERSION (rtp->map[0].data);
+  return GST_RTP_HEADER_VERSION (rtp->data[0]);
 }
 
 /**
@@ -544,7 +529,7 @@ gst_rtp_buffer_set_version (GstRTPBuffer * rtp, guint8 version)
 {
   g_return_if_fail (version < 0x04);
 
-  GST_RTP_HEADER_VERSION (rtp->map[0].data) = version;
+  GST_RTP_HEADER_VERSION (rtp->data[0]) = version;
 }
 
 /**
@@ -558,7 +543,7 @@ gst_rtp_buffer_set_version (GstRTPBuffer * rtp, guint8 version)
 gboolean
 gst_rtp_buffer_get_padding (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_PADDING (rtp->map[0].data);
+  return GST_RTP_HEADER_PADDING (rtp->data[0]);
 }
 
 /**
@@ -571,7 +556,7 @@ gst_rtp_buffer_get_padding (GstRTPBuffer * rtp)
 void
 gst_rtp_buffer_set_padding (GstRTPBuffer * rtp, gboolean padding)
 {
-  GST_RTP_HEADER_PADDING (rtp->map[0].data) = padding;
+  GST_RTP_HEADER_PADDING (rtp->data[0]) = padding;
 }
 
 /**
@@ -589,7 +574,7 @@ gst_rtp_buffer_pad_to (GstRTPBuffer * rtp, guint len)
 {
   guint8 *data;
 
-  data = rtp->map[0].data;
+  data = rtp->data[0];
 
   if (len > 0)
     GST_RTP_HEADER_PADDING (data) = TRUE;
@@ -610,7 +595,7 @@ gst_rtp_buffer_pad_to (GstRTPBuffer * rtp, guint len)
 gboolean
 gst_rtp_buffer_get_extension (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_EXTENSION (rtp->map[0].data);
+  return GST_RTP_HEADER_EXTENSION (rtp->data[0]);
 }
 
 /**
@@ -623,7 +608,7 @@ gst_rtp_buffer_get_extension (GstRTPBuffer * rtp)
 void
 gst_rtp_buffer_set_extension (GstRTPBuffer * rtp, gboolean extension)
 {
-  GST_RTP_HEADER_EXTENSION (rtp->map[0].data) = extension;
+  GST_RTP_HEADER_EXTENSION (rtp->data[0]) = extension;
 }
 
 /**
@@ -646,17 +631,12 @@ gboolean
 gst_rtp_buffer_get_extension_data (GstRTPBuffer * rtp, guint16 * bits,
     gpointer * data, guint * wordlen)
 {
-  guint len;
   guint8 *pdata;
 
-  pdata = rtp->map[0].data;
-
-  if (!GST_RTP_HEADER_EXTENSION (pdata))
-    return FALSE;
-
   /* move to the extension */
-  len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (pdata);
-  pdata += len;
+  pdata = rtp->data[1];
+  if (!pdata)
+    return FALSE;
 
   if (bits)
     *bits = GST_READ_UINT16_BE (pdata);
@@ -689,19 +669,18 @@ gst_rtp_buffer_set_extension_data (GstRTPBuffer * rtp, guint16 bits,
   guint32 min_size = 0;
   guint8 *data;
 
-  data = rtp->map[0].data;
+  /* FIXME, we should allocate and map the extension data */
+  data = rtp->data[0];
 
   /* check if the buffer is big enough to hold the extension */
-  min_size =
-      GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data) + 4 +
-      length * sizeof (guint32);
-  if (G_UNLIKELY (min_size > rtp->map[0].size))
+  min_size = 4 + length * sizeof (guint32);
+  if (G_UNLIKELY (min_size > rtp->size[1]))
     goto too_small;
 
   /* now we can set the extension bit */
-  GST_RTP_HEADER_EXTENSION (rtp->map[0].data) = TRUE;
+  GST_RTP_HEADER_EXTENSION (data) = TRUE;
 
-  data += GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
+  data = rtp->data[1];
   GST_WRITE_UINT16_BE (data, bits);
   GST_WRITE_UINT16_BE (data + 2, length);
 
@@ -712,7 +691,7 @@ too_small:
   {
     g_warning
         ("rtp buffer too small: need more than %d bytes but only have %"
-        G_GSIZE_FORMAT " bytes", min_size, rtp->map[0].size);
+        G_GSIZE_FORMAT " bytes", min_size, rtp->size[1]);
     return FALSE;
   }
 }
@@ -728,7 +707,7 @@ too_small:
 guint32
 gst_rtp_buffer_get_ssrc (GstRTPBuffer * rtp)
 {
-  return g_ntohl (GST_RTP_HEADER_SSRC (rtp->map[0].data));
+  return g_ntohl (GST_RTP_HEADER_SSRC (rtp->data[0]));
 }
 
 /**
@@ -741,7 +720,7 @@ gst_rtp_buffer_get_ssrc (GstRTPBuffer * rtp)
 void
 gst_rtp_buffer_set_ssrc (GstRTPBuffer * rtp, guint32 ssrc)
 {
-  GST_RTP_HEADER_SSRC (rtp->map[0].data) = g_htonl (ssrc);
+  GST_RTP_HEADER_SSRC (rtp->data[0]) = g_htonl (ssrc);
 }
 
 /**
@@ -755,7 +734,7 @@ gst_rtp_buffer_set_ssrc (GstRTPBuffer * rtp, guint32 ssrc)
 guint8
 gst_rtp_buffer_get_csrc_count (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_CSRC_COUNT (rtp->map[0].data);
+  return GST_RTP_HEADER_CSRC_COUNT (rtp->data[0]);
 }
 
 /**
@@ -772,7 +751,7 @@ gst_rtp_buffer_get_csrc (GstRTPBuffer * rtp, guint8 idx)
 {
   guint8 *data;
 
-  data = rtp->map[0].data;
+  data = rtp->data[0];
 
   g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data), 0);
 
@@ -792,7 +771,7 @@ gst_rtp_buffer_set_csrc (GstRTPBuffer * rtp, guint8 idx, guint32 csrc)
 {
   guint8 *data;
 
-  data = rtp->map[0].data;
+  data = rtp->data[0];
 
   g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data));
 
@@ -810,7 +789,7 @@ gst_rtp_buffer_set_csrc (GstRTPBuffer * rtp, guint8 idx, guint32 csrc)
 gboolean
 gst_rtp_buffer_get_marker (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_MARKER (rtp->map[0].data);
+  return GST_RTP_HEADER_MARKER (rtp->data[0]);
 }
 
 /**
@@ -823,7 +802,7 @@ gst_rtp_buffer_get_marker (GstRTPBuffer * rtp)
 void
 gst_rtp_buffer_set_marker (GstRTPBuffer * rtp, gboolean marker)
 {
-  GST_RTP_HEADER_MARKER (rtp->map[0].data) = marker;
+  GST_RTP_HEADER_MARKER (rtp->data[0]) = marker;
 }
 
 /**
@@ -837,7 +816,7 @@ gst_rtp_buffer_set_marker (GstRTPBuffer * rtp, gboolean marker)
 guint8
 gst_rtp_buffer_get_payload_type (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_PAYLOAD_TYPE (rtp->map[0].data);
+  return GST_RTP_HEADER_PAYLOAD_TYPE (rtp->data[0]);
 }
 
 /**
@@ -852,7 +831,7 @@ gst_rtp_buffer_set_payload_type (GstRTPBuffer * rtp, guint8 payload_type)
 {
   g_return_if_fail (payload_type < 0x80);
 
-  GST_RTP_HEADER_PAYLOAD_TYPE (rtp->map[0].data) = payload_type;
+  GST_RTP_HEADER_PAYLOAD_TYPE (rtp->data[0]) = payload_type;
 }
 
 /**
@@ -866,7 +845,7 @@ gst_rtp_buffer_set_payload_type (GstRTPBuffer * rtp, guint8 payload_type)
 guint16
 gst_rtp_buffer_get_seq (GstRTPBuffer * rtp)
 {
-  return g_ntohs (GST_RTP_HEADER_SEQ (rtp->map[0].data));
+  return g_ntohs (GST_RTP_HEADER_SEQ (rtp->data[0]));
 }
 
 /**
@@ -879,7 +858,7 @@ gst_rtp_buffer_get_seq (GstRTPBuffer * rtp)
 void
 gst_rtp_buffer_set_seq (GstRTPBuffer * rtp, guint16 seq)
 {
-  GST_RTP_HEADER_SEQ (rtp->map[0].data) = g_htons (seq);
+  GST_RTP_HEADER_SEQ (rtp->data[0]) = g_htons (seq);
 }
 
 /**
@@ -893,7 +872,7 @@ gst_rtp_buffer_set_seq (GstRTPBuffer * rtp, guint16 seq)
 guint32
 gst_rtp_buffer_get_timestamp (GstRTPBuffer * rtp)
 {
-  return g_ntohl (GST_RTP_HEADER_TIMESTAMP (rtp->map[0].data));
+  return g_ntohl (GST_RTP_HEADER_TIMESTAMP (rtp->data[0]));
 }
 
 /**
@@ -906,7 +885,7 @@ gst_rtp_buffer_get_timestamp (GstRTPBuffer * rtp)
 void
 gst_rtp_buffer_set_timestamp (GstRTPBuffer * rtp, guint32 timestamp)
 {
-  GST_RTP_HEADER_TIMESTAMP (rtp->map[0].data) = g_htonl (timestamp);
+  GST_RTP_HEADER_TIMESTAMP (rtp->data[0]) = g_htonl (timestamp);
 }
 
 
@@ -979,18 +958,8 @@ gst_rtp_buffer_get_payload_buffer (GstRTPBuffer * rtp)
 guint
 gst_rtp_buffer_get_payload_len (GstRTPBuffer * rtp)
 {
-  guint len, size;
-  guint8 *data;
-
-  size = rtp->map[0].size;
-  data = rtp->map[0].data;
-
-  len = size - gst_rtp_buffer_get_header_len (rtp);
-
-  if (GST_RTP_HEADER_PADDING (data))
-    len -= data[size - 1];
-
-  return len;
+  return gst_buffer_get_size (rtp->buffer) - gst_rtp_buffer_get_header_len (rtp)
+      - rtp->size[3];
 }
 
 /**
@@ -1006,7 +975,27 @@ gst_rtp_buffer_get_payload_len (GstRTPBuffer * rtp)
 gpointer
 gst_rtp_buffer_get_payload (GstRTPBuffer * rtp)
 {
-  return rtp->map[0].data + gst_rtp_buffer_get_header_len (rtp);
+  guint hlen, plen;
+  guint idx, length;
+  gsize skip;
+
+  if (rtp->data[2])
+    return rtp->data[2];
+
+  hlen = gst_rtp_buffer_get_header_len (rtp);
+  plen = gst_buffer_get_size (rtp->buffer) - hlen - rtp->size[3];
+
+  if (!gst_buffer_find_memory (rtp->buffer, hlen, plen, &idx, &length, &skip))
+    return NULL;
+
+  if (!gst_buffer_map_range (rtp->buffer, idx, length, &rtp->map[2],
+          rtp->map[0].flags))
+    return NULL;
+
+  rtp->data[2] = rtp->map[2].data + skip;
+  rtp->size[2] = plen;
+
+  return rtp->data[2];
 }
 
 /**
index bc7dcdc..6b6b755 100644 (file)
@@ -54,11 +54,13 @@ struct _GstRTPBuffer
   GstBuffer   *buffer;
   guint        state;
   guint        n_map;
+  gpointer     data[4];
+  gsize        size[4];
   GstMapInfo   map[4];
 };
 
-#define GST_RTP_BUFFER_INIT { NULL, 0, 0, { GST_MAP_INFO_INIT, GST_MAP_INFO_INIT, \
-                                            GST_MAP_INFO_INIT, GST_MAP_INFO_INIT} }
+#define GST_RTP_BUFFER_INIT { NULL, 0, 0, { NULL, NULL, NULL, NULL}, { 0, 0, 0, 0 }, \
+  { GST_MAP_INFO_INIT, GST_MAP_INFO_INIT, GST_MAP_INFO_INIT, GST_MAP_INFO_INIT} }
 
 /* creating buffers */
 void            gst_rtp_buffer_allocate_data         (GstBuffer *buffer, guint payload_len,
@@ -73,12 +75,8 @@ guint           gst_rtp_buffer_calc_header_len       (guint8 csrc_count);
 guint           gst_rtp_buffer_calc_packet_len       (guint payload_len, guint8 pad_len, guint8 csrc_count);
 guint           gst_rtp_buffer_calc_payload_len      (guint packet_len, guint8 pad_len, guint8 csrc_count);
 
-gboolean        gst_rtp_buffer_validate_data         (guint8 *data, gsize len);
-gboolean        gst_rtp_buffer_validate              (GstBuffer *buffer);
-
-
 gboolean        gst_rtp_buffer_map                   (GstBuffer *buffer, GstMapFlags flags, GstRTPBuffer *rtp);
-gboolean        gst_rtp_buffer_unmap                 (GstRTPBuffer *rtp);
+void            gst_rtp_buffer_unmap                 (GstRTPBuffer *rtp);
 
 void            gst_rtp_buffer_set_packet_len        (GstRTPBuffer *rtp, guint len);
 guint           gst_rtp_buffer_get_packet_len        (GstRTPBuffer *rtp);
index cb2843a..8edfd06 100644 (file)
@@ -157,10 +157,11 @@ GST_START_TEST (test_rtp_buffer_validate_corrupt)
     0xaf, 0xd6, 0x1b, 0x29, 0x40, 0xe0, 0xa5, 0x83, 0x01, 0x4b, 0x04, 0x02,
     0xb0, 0x97, 0x63, 0x08, 0x10, 0x4b, 0x43, 0x85, 0x37, 0x2c
   };
+  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
 
   buf = gst_buffer_new_and_alloc (sizeof (corrupt_rtp_packet));
   gst_buffer_fill (buf, 0, corrupt_rtp_packet, sizeof (corrupt_rtp_packet));
-  fail_if (gst_rtp_buffer_validate (buf));
+  fail_if (gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp));
   gst_buffer_unref (buf);
 }