mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
rtp: Add support for multiple memory blocks in RTP
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.
This commit is contained in:
parent
5d82addc2f
commit
11a494d5c9
7 changed files with 164 additions and 176 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
/* skip id */
|
||||
extpos += 2;
|
||||
/* read length as the number of 32 bits words */
|
||||
extlen = GST_READ_UINT16_BE (extpos);
|
||||
if (!gst_buffer_map_range (buffer, idx, length, &rtp->map[1], flags))
|
||||
goto map_failed;
|
||||
|
||||
header_len += extlen * sizeof (guint32);
|
||||
extdata = rtp->data[1] = rtp->map[1].data + skip;
|
||||
/* skip id */
|
||||
extdata += 2;
|
||||
/* read length as the number of 32 bits words */
|
||||
extlen = GST_READ_UINT16_BE (extdata);
|
||||
|
||||
rtp->size[1] = 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
|
||||
* gst_rtp_buffer_unmap:
|
||||
* @rtp: a #GstRTPBuffer
|
||||
*
|
||||
* 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.
|
||||
* Unmap @rtp previously mapped with gst_rtp_buffer_map().
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* Returns: TRUE if @buffer is a valid RTP packet.
|
||||
*/
|
||||
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;
|
||||
|
||||
gst_buffer_unmap (rtp->buffer, &rtp->map[0]);
|
||||
g_return_if_fail (rtp != NULL);
|
||||
g_return_if_fail (rtp->buffer != NULL);
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue