2 * Copyright (C) <2005> Philippe Khalaf <burger@speedy.org>
3 * Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * SECTION:gstrtpbuffer
23 * @short_description: Helper methods for dealing with RTP buffers
24 * @see_also: #GstRTPBasePayload, #GstRTPBaseDepayload, gstrtcpbuffer
28 * The GstRTPBuffer helper functions makes it easy to parse and create regular
29 * #GstBuffer objects that contain RTP payloads. These buffers are typically of
30 * 'application/x-rtp' #GstCaps.
34 * Last reviewed on 2006-07-17 (0.10.10)
37 #include "gstrtpbuffer.h"
42 #define GST_RTP_HEADER_LEN 12
44 /* Note: we use bitfields here to make sure the compiler doesn't add padding
45 * between fields on certain architectures; can't assume aligned access either
47 typedef struct _GstRTPHeader
49 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
50 unsigned int csrc_count:4; /* CSRC count */
51 unsigned int extension:1; /* header extension flag */
52 unsigned int padding:1; /* padding flag */
53 unsigned int version:2; /* protocol version */
54 unsigned int payload_type:7; /* payload type */
55 unsigned int marker:1; /* marker bit */
56 #elif G_BYTE_ORDER == G_BIG_ENDIAN
57 unsigned int version:2; /* protocol version */
58 unsigned int padding:1; /* padding flag */
59 unsigned int extension:1; /* header extension flag */
60 unsigned int csrc_count:4; /* CSRC count */
61 unsigned int marker:1; /* marker bit */
62 unsigned int payload_type:7; /* payload type */
64 #error "G_BYTE_ORDER should be big or little endian."
66 unsigned int seq:16; /* sequence number */
67 unsigned int timestamp:32; /* timestamp */
68 unsigned int ssrc:32; /* synchronization source */
69 guint8 csrclist[4]; /* optional CSRC list, 32 bits each */
72 #define GST_RTP_HEADER_VERSION(data) (((GstRTPHeader *)(data))->version)
73 #define GST_RTP_HEADER_PADDING(data) (((GstRTPHeader *)(data))->padding)
74 #define GST_RTP_HEADER_EXTENSION(data) (((GstRTPHeader *)(data))->extension)
75 #define GST_RTP_HEADER_CSRC_COUNT(data) (((GstRTPHeader *)(data))->csrc_count)
76 #define GST_RTP_HEADER_MARKER(data) (((GstRTPHeader *)(data))->marker)
77 #define GST_RTP_HEADER_PAYLOAD_TYPE(data) (((GstRTPHeader *)(data))->payload_type)
78 #define GST_RTP_HEADER_SEQ(data) (((GstRTPHeader *)(data))->seq)
79 #define GST_RTP_HEADER_TIMESTAMP(data) (((GstRTPHeader *)(data))->timestamp)
80 #define GST_RTP_HEADER_SSRC(data) (((GstRTPHeader *)(data))->ssrc)
81 #define GST_RTP_HEADER_CSRC_LIST_OFFSET(data,i) \
82 data + G_STRUCT_OFFSET(GstRTPHeader, csrclist) + \
83 ((i) * sizeof(guint32))
84 #define GST_RTP_HEADER_CSRC_SIZE(data) (GST_RTP_HEADER_CSRC_COUNT(data) * sizeof (guint32))
87 * gst_rtp_buffer_allocate_data:
88 * @buffer: a #GstBuffer
89 * @payload_len: the length of the payload
90 * @pad_len: the amount of padding
91 * @csrc_count: the number of CSRC entries
93 * Allocate enough data in @buffer to hold an RTP packet with @csrc_count CSRCs,
94 * a payload length of @payload_len and padding of @pad_len.
95 * @buffer must be writable and all previous memory in @buffer will be freed.
96 * All other RTP header fields will be set to 0/FALSE.
99 gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
100 guint8 pad_len, guint8 csrc_count)
106 g_return_if_fail (csrc_count <= 15);
107 g_return_if_fail (GST_IS_BUFFER (buffer));
108 g_return_if_fail (gst_buffer_is_writable (buffer));
110 gst_buffer_remove_all_memory (buffer);
112 len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
113 + payload_len + pad_len;
115 mem = gst_allocator_alloc (NULL, len, NULL);
117 gst_memory_map (mem, &map, GST_MAP_WRITE);
118 /* fill in defaults */
119 GST_RTP_HEADER_VERSION (map.data) = GST_RTP_VERSION;
120 GST_RTP_HEADER_PADDING (map.data) = FALSE;
121 GST_RTP_HEADER_EXTENSION (map.data) = FALSE;
122 GST_RTP_HEADER_CSRC_COUNT (map.data) = csrc_count;
123 memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (map.data, 0), 0,
124 csrc_count * sizeof (guint32));
125 GST_RTP_HEADER_MARKER (map.data) = FALSE;
126 GST_RTP_HEADER_PAYLOAD_TYPE (map.data) = 0;
127 GST_RTP_HEADER_SEQ (map.data) = 0;
128 GST_RTP_HEADER_TIMESTAMP (map.data) = 0;
129 GST_RTP_HEADER_SSRC (map.data) = 0;
130 gst_memory_unmap (mem, &map);
132 gst_buffer_append_memory (buffer, mem);
136 * gst_rtp_buffer_new_take_data:
137 * @data: (array length=len) (transfer full) (element-type guint8):
138 * data for the new buffer
139 * @len: the length of data
141 * Create a new buffer and set the data and size of the buffer to @data and @len
142 * respectively. @data will be freed when the buffer is unreffed, so this
143 * function transfers ownership of @data to the new buffer.
145 * Returns: A newly allocated buffer with @data and of size @len.
148 gst_rtp_buffer_new_take_data (gpointer data, gsize len)
150 g_return_val_if_fail (data != NULL, NULL);
151 g_return_val_if_fail (len > 0, NULL);
153 return gst_buffer_new_wrapped (data, len);
157 * gst_rtp_buffer_new_copy_data:
158 * @data: (array length=len) (element-type guint8): data for the new
160 * @len: the length of data
162 * Create a new buffer and set the data to a copy of @len
163 * bytes of @data and the size to @len. The data will be freed when the buffer
166 * Returns: A newly allocated buffer with a copy of @data and of size @len.
169 gst_rtp_buffer_new_copy_data (gpointer data, gsize len)
171 return gst_rtp_buffer_new_take_data (g_memdup (data, len), len);
175 * gst_rtp_buffer_new_allocate:
176 * @payload_len: the length of the payload
177 * @pad_len: the amount of padding
178 * @csrc_count: the number of CSRC entries
180 * Allocate a new #GstBuffer with enough data to hold an RTP packet with
181 * @csrc_count CSRCs, a payload length of @payload_len and padding of @pad_len.
182 * All other RTP header fields will be set to 0/FALSE.
184 * Returns: A newly allocated buffer that can hold an RTP packet with given
188 gst_rtp_buffer_new_allocate (guint payload_len, guint8 pad_len,
193 g_return_val_if_fail (csrc_count <= 15, NULL);
195 result = gst_buffer_new ();
196 gst_rtp_buffer_allocate_data (result, payload_len, pad_len, csrc_count);
202 * gst_rtp_buffer_new_allocate_len:
203 * @packet_len: the total length of the packet
204 * @pad_len: the amount of padding
205 * @csrc_count: the number of CSRC entries
207 * Create a new #GstBuffer that can hold an RTP packet that is exactly
208 * @packet_len long. The length of the payload depends on @pad_len and
209 * @csrc_count and can be calculated with gst_rtp_buffer_calc_payload_len().
210 * All RTP header fields will be set to 0/FALSE.
212 * Returns: A newly allocated buffer that can hold an RTP packet of @packet_len.
215 gst_rtp_buffer_new_allocate_len (guint packet_len, guint8 pad_len,
220 g_return_val_if_fail (csrc_count <= 15, NULL);
222 len = gst_rtp_buffer_calc_payload_len (packet_len, pad_len, csrc_count);
224 return gst_rtp_buffer_new_allocate (len, pad_len, csrc_count);
228 * gst_rtp_buffer_calc_header_len:
229 * @csrc_count: the number of CSRC entries
231 * Calculate the header length of an RTP packet with @csrc_count CSRC entries.
232 * An RTP packet can have at most 15 CSRC entries.
234 * Returns: The length of an RTP header with @csrc_count CSRC entries.
237 gst_rtp_buffer_calc_header_len (guint8 csrc_count)
239 g_return_val_if_fail (csrc_count <= 15, 0);
241 return GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32));
245 * gst_rtp_buffer_calc_packet_len:
246 * @payload_len: the length of the payload
247 * @pad_len: the amount of padding
248 * @csrc_count: the number of CSRC entries
250 * Calculate the total length of an RTP packet with a payload size of @payload_len,
251 * a padding of @pad_len and a @csrc_count CSRC entries.
253 * Returns: The total length of an RTP header with given parameters.
256 gst_rtp_buffer_calc_packet_len (guint payload_len, guint8 pad_len,
259 g_return_val_if_fail (csrc_count <= 15, 0);
261 return payload_len + GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32))
266 * gst_rtp_buffer_calc_payload_len:
267 * @packet_len: the length of the total RTP packet
268 * @pad_len: the amount of padding
269 * @csrc_count: the number of CSRC entries
271 * Calculate the length of the payload of an RTP packet with size @packet_len,
272 * a padding of @pad_len and a @csrc_count CSRC entries.
274 * Returns: The length of the payload of an RTP packet with given parameters.
277 gst_rtp_buffer_calc_payload_len (guint packet_len, guint8 pad_len,
280 g_return_val_if_fail (csrc_count <= 15, 0);
282 return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32))
287 * gst_rtp_buffer_map:
288 * @buffer: a #GstBuffer
289 * @flags: #GstMapFlags
290 * @rtp: (out): a #GstRTPBuffer
292 * Map the contents of @buffer into @rtp.
294 * Returns: %TRUE if @buffer could be mapped.
297 gst_rtp_buffer_map (GstBuffer * buffer, GstMapFlags flags, GstRTPBuffer * rtp)
308 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
309 g_return_val_if_fail (rtp != NULL, FALSE);
310 g_return_val_if_fail (rtp->buffer == NULL, FALSE);
312 /* map first memory, this should be the header */
313 if (!gst_buffer_map_range (buffer, 0, 1, &rtp->map[0], flags))
316 data = rtp->data[0] = rtp->map[0].data;
317 size = rtp->map[0].size;
319 header_len = GST_RTP_HEADER_LEN;
320 if (G_UNLIKELY (size < header_len))
324 version = (data[0] & 0xc0);
325 if (G_UNLIKELY (version != (GST_RTP_VERSION << 6)))
328 /* calc header length with csrc */
329 csrc_count = (data[0] & 0x0f);
330 header_len += csrc_count * sizeof (guint32);
332 rtp->size[0] = header_len;
334 bufsize = gst_buffer_get_size (buffer);
336 /* calc extension length when present. */
337 if (data[0] & 0x10) {
341 /* find memory for the extension bits */
342 if (!gst_buffer_find_memory (buffer, header_len, 4, &idx, &length, &skip))
345 if (!gst_buffer_map_range (buffer, idx, length, &rtp->map[1], flags))
348 extdata = rtp->data[1] = rtp->map[1].data + skip;
351 /* read length as the number of 32 bits words */
352 extlen = GST_READ_UINT16_BE (extdata);
354 rtp->size[1] = extlen * sizeof (guint32);
356 header_len += rtp->size[1];
362 /* check for padding */
363 if (data[0] & 0x20) {
364 /* find memory for the padding bits */
365 if (!gst_buffer_find_memory (buffer, bufsize - 1, 1, &idx, &length, &skip))
368 if (!gst_buffer_map_range (buffer, idx, length, &rtp->map[3], flags))
371 padding = rtp->map[3].data[skip];
372 if (skip + 1 < padding)
375 rtp->data[3] = rtp->map[3].data + skip + 1 - padding;
376 rtp->size[3] = padding;
383 /* check if padding and header not bigger than packet length */
384 if (G_UNLIKELY (bufsize < padding + header_len))
387 rtp->buffer = buffer;
388 /* we have not yet mapped the payload */
399 GST_ERROR ("failed to map memory");
404 GST_DEBUG ("length check failed");
409 GST_DEBUG ("version check failed (%d != %d)", version, GST_RTP_VERSION);
414 GST_DEBUG ("padding check failed (%" G_GSIZE_FORMAT " - %d < %d)", bufsize,
415 header_len, padding);
420 GST_MEMDUMP ("buffer", data, size);
426 * gst_rtp_buffer_unmap:
427 * @rtp: a #GstRTPBuffer
429 * Unmap @rtp previously mapped with gst_rtp_buffer_map().
432 gst_rtp_buffer_unmap (GstRTPBuffer * rtp)
436 g_return_if_fail (rtp != NULL);
437 g_return_if_fail (rtp->buffer != NULL);
439 for (i = 0; i < 4; i++) {
441 gst_buffer_unmap (rtp->buffer, &rtp->map[i]);
449 * gst_rtp_buffer_set_packet_len:
450 * @rtp: the RTP packet
451 * @len: the new packet length
453 * Set the total @rtp size to @len. The data in the buffer will be made
454 * larger if needed. Any padding will be removed from the packet.
457 gst_rtp_buffer_set_packet_len (GstRTPBuffer * rtp, guint len)
465 if (rtp->map[0].maxsize <= len) {
466 /* FIXME, realloc bigger space */
467 g_warning ("not implemented");
470 gst_buffer_set_size (rtp->buffer, len);
471 rtp->map[0].size = len;
473 /* remove any padding */
474 GST_RTP_HEADER_PADDING (data) = FALSE;
478 * gst_rtp_buffer_get_packet_len:
479 * @rtp: the RTP packet
481 * Return the total length of the packet in @buffer.
483 * Returns: The total length of the packet in @buffer.
486 gst_rtp_buffer_get_packet_len (GstRTPBuffer * rtp)
488 return gst_buffer_get_size (rtp->buffer);
492 * gst_rtp_buffer_get_header_len:
493 * @rtp: the RTP packet
495 * Return the total length of the header in @buffer. This include the length of
496 * the fixed header, the CSRC list and the extension header.
498 * Returns: The total length of the header in @buffer.
501 gst_rtp_buffer_get_header_len (GstRTPBuffer * rtp)
503 return rtp->size[0] + rtp->size[1];
507 * gst_rtp_buffer_get_version:
508 * @rtp: the RTP packet
510 * Get the version number of the RTP packet in @buffer.
512 * Returns: The version of @buffer.
515 gst_rtp_buffer_get_version (GstRTPBuffer * rtp)
517 return GST_RTP_HEADER_VERSION (rtp->data[0]);
521 * gst_rtp_buffer_set_version:
522 * @rtp: the RTP packet
523 * @version: the new version
525 * Set the version of the RTP packet in @buffer to @version.
528 gst_rtp_buffer_set_version (GstRTPBuffer * rtp, guint8 version)
530 g_return_if_fail (version < 0x04);
532 GST_RTP_HEADER_VERSION (rtp->data[0]) = version;
536 * gst_rtp_buffer_get_padding:
537 * @rtp: the RTP packet
539 * Check if the padding bit is set on the RTP packet in @buffer.
541 * Returns: TRUE if @buffer has the padding bit set.
544 gst_rtp_buffer_get_padding (GstRTPBuffer * rtp)
546 return GST_RTP_HEADER_PADDING (rtp->data[0]);
550 * gst_rtp_buffer_set_padding:
552 * @padding: the new padding
554 * Set the padding bit on the RTP packet in @buffer to @padding.
557 gst_rtp_buffer_set_padding (GstRTPBuffer * rtp, gboolean padding)
559 GST_RTP_HEADER_PADDING (rtp->data[0]) = padding;
563 * gst_rtp_buffer_pad_to:
564 * @rtp: the RTP packet
565 * @len: the new amount of padding
567 * Set the amount of padding in the RTP packet in @buffer to
568 * @len. If @len is 0, the padding is removed.
570 * NOTE: This function does not work correctly.
573 gst_rtp_buffer_pad_to (GstRTPBuffer * rtp, guint len)
580 GST_RTP_HEADER_PADDING (data) = TRUE;
582 GST_RTP_HEADER_PADDING (data) = FALSE;
584 /* FIXME, set the padding byte at the end of the payload data */
588 * gst_rtp_buffer_get_extension:
589 * @rtp: the RTP packet
591 * Check if the extension bit is set on the RTP packet in @buffer.
593 * Returns: TRUE if @buffer has the extension bit set.
596 gst_rtp_buffer_get_extension (GstRTPBuffer * rtp)
598 return GST_RTP_HEADER_EXTENSION (rtp->data[0]);
602 * gst_rtp_buffer_set_extension:
603 * @rtp: the RTP packet
604 * @extension: the new extension
606 * Set the extension bit on the RTP packet in @buffer to @extension.
609 gst_rtp_buffer_set_extension (GstRTPBuffer * rtp, gboolean extension)
611 GST_RTP_HEADER_EXTENSION (rtp->data[0]) = extension;
615 * gst_rtp_buffer_get_extension_data:
616 * @rtp: the RTP packet
617 * @bits: (out): location for result bits
618 * @data: (out) (array) (element-type guint8) (transfer none): location for data
619 * @wordlen: (out): location for length of @data in 32 bits words
621 * Get the extension data. @bits will contain the extension 16 bits of custom
622 * data. @data will point to the data in the extension and @wordlen will contain
623 * the length of @data in 32 bits words.
625 * If @buffer did not contain an extension, this function will return %FALSE
626 * with @bits, @data and @wordlen unchanged.
628 * Returns: TRUE if @buffer had the extension bit set.
631 gst_rtp_buffer_get_extension_data (GstRTPBuffer * rtp, guint16 * bits,
632 gpointer * data, guint * wordlen)
636 /* move to the extension */
637 pdata = rtp->data[1];
642 *bits = GST_READ_UINT16_BE (pdata);
644 *wordlen = GST_READ_UINT16_BE (pdata + 2);
647 *data = (gpointer *) pdata;
653 * gst_rtp_buffer_set_extension_data:
654 * @rtp: the RTP packet
655 * @bits: the bits specific for the extension
656 * @length: the length that counts the number of 32-bit words in
657 * the extension, excluding the extension header ( therefore zero is a valid length)
659 * Set the extension bit of the rtp buffer and fill in the @bits and @length of the
660 * extension header. It will refuse to set the extension data if the buffer is not
663 * Returns: True if done.
666 gst_rtp_buffer_set_extension_data (GstRTPBuffer * rtp, guint16 bits,
669 guint32 min_size = 0;
672 /* FIXME, we should allocate and map the extension data */
675 /* check if the buffer is big enough to hold the extension */
676 min_size = 4 + length * sizeof (guint32);
677 if (G_UNLIKELY (min_size > rtp->size[1]))
680 /* now we can set the extension bit */
681 GST_RTP_HEADER_EXTENSION (data) = TRUE;
684 GST_WRITE_UINT16_BE (data, bits);
685 GST_WRITE_UINT16_BE (data + 2, length);
693 ("rtp buffer too small: need more than %d bytes but only have %"
694 G_GSIZE_FORMAT " bytes", min_size, rtp->size[1]);
700 * gst_rtp_buffer_get_ssrc:
701 * @rtp: the RTP packet
703 * Get the SSRC of the RTP packet in @buffer.
705 * Returns: the SSRC of @buffer in host order.
708 gst_rtp_buffer_get_ssrc (GstRTPBuffer * rtp)
710 return g_ntohl (GST_RTP_HEADER_SSRC (rtp->data[0]));
714 * gst_rtp_buffer_set_ssrc:
715 * @rtp: the RTP packet
716 * @ssrc: the new SSRC
718 * Set the SSRC on the RTP packet in @buffer to @ssrc.
721 gst_rtp_buffer_set_ssrc (GstRTPBuffer * rtp, guint32 ssrc)
723 GST_RTP_HEADER_SSRC (rtp->data[0]) = g_htonl (ssrc);
727 * gst_rtp_buffer_get_csrc_count:
728 * @rtp: the RTP packet
730 * Get the CSRC count of the RTP packet in @buffer.
732 * Returns: the CSRC count of @buffer.
735 gst_rtp_buffer_get_csrc_count (GstRTPBuffer * rtp)
737 return GST_RTP_HEADER_CSRC_COUNT (rtp->data[0]);
741 * gst_rtp_buffer_get_csrc:
742 * @rtp: the RTP packet
743 * @idx: the index of the CSRC to get
745 * Get the CSRC at index @idx in @buffer.
747 * Returns: the CSRC at index @idx in host order.
750 gst_rtp_buffer_get_csrc (GstRTPBuffer * rtp, guint8 idx)
756 g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data), 0);
758 return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx));
762 * gst_rtp_buffer_set_csrc:
763 * @rtp: the RTP packet
764 * @idx: the CSRC index to set
765 * @csrc: the CSRC in host order to set at @idx
767 * Modify the CSRC at index @idx in @buffer to @csrc.
770 gst_rtp_buffer_set_csrc (GstRTPBuffer * rtp, guint8 idx, guint32 csrc)
776 g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data));
778 GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx), csrc);
782 * gst_rtp_buffer_get_marker:
783 * @rtp: the RTP packet
785 * Check if the marker bit is set on the RTP packet in @buffer.
787 * Returns: TRUE if @buffer has the marker bit set.
790 gst_rtp_buffer_get_marker (GstRTPBuffer * rtp)
792 return GST_RTP_HEADER_MARKER (rtp->data[0]);
796 * gst_rtp_buffer_set_marker:
797 * @rtp: the RTP packet
798 * @marker: the new marker
800 * Set the marker bit on the RTP packet in @buffer to @marker.
803 gst_rtp_buffer_set_marker (GstRTPBuffer * rtp, gboolean marker)
805 GST_RTP_HEADER_MARKER (rtp->data[0]) = marker;
809 * gst_rtp_buffer_get_payload_type:
810 * @rtp: the RTP packet
812 * Get the payload type of the RTP packet in @buffer.
814 * Returns: The payload type.
817 gst_rtp_buffer_get_payload_type (GstRTPBuffer * rtp)
819 return GST_RTP_HEADER_PAYLOAD_TYPE (rtp->data[0]);
823 * gst_rtp_buffer_set_payload_type:
824 * @rtp: the RTP packet
825 * @payload_type: the new type
827 * Set the payload type of the RTP packet in @buffer to @payload_type.
830 gst_rtp_buffer_set_payload_type (GstRTPBuffer * rtp, guint8 payload_type)
832 g_return_if_fail (payload_type < 0x80);
834 GST_RTP_HEADER_PAYLOAD_TYPE (rtp->data[0]) = payload_type;
838 * gst_rtp_buffer_get_seq:
839 * @rtp: the RTP packet
841 * Get the sequence number of the RTP packet in @buffer.
843 * Returns: The sequence number in host order.
846 gst_rtp_buffer_get_seq (GstRTPBuffer * rtp)
848 return g_ntohs (GST_RTP_HEADER_SEQ (rtp->data[0]));
852 * gst_rtp_buffer_set_seq:
853 * @rtp: the RTP packet
854 * @seq: the new sequence number
856 * Set the sequence number of the RTP packet in @buffer to @seq.
859 gst_rtp_buffer_set_seq (GstRTPBuffer * rtp, guint16 seq)
861 GST_RTP_HEADER_SEQ (rtp->data[0]) = g_htons (seq);
865 * gst_rtp_buffer_get_timestamp:
866 * @rtp: the RTP packet
868 * Get the timestamp of the RTP packet in @buffer.
870 * Returns: The timestamp in host order.
873 gst_rtp_buffer_get_timestamp (GstRTPBuffer * rtp)
875 return g_ntohl (GST_RTP_HEADER_TIMESTAMP (rtp->data[0]));
879 * gst_rtp_buffer_set_timestamp:
880 * @rtp: the RTP packet
881 * @timestamp: the new timestamp
883 * Set the timestamp of the RTP packet in @buffer to @timestamp.
886 gst_rtp_buffer_set_timestamp (GstRTPBuffer * rtp, guint32 timestamp)
888 GST_RTP_HEADER_TIMESTAMP (rtp->data[0]) = g_htonl (timestamp);
893 * gst_rtp_buffer_get_payload_subbuffer:
894 * @rtp: the RTP packet
895 * @offset: the offset in the payload
896 * @len: the length in the payload
898 * Create a subbuffer of the payload of the RTP packet in @buffer. @offset bytes
899 * are skipped in the payload and the subbuffer will be of size @len.
900 * If @len is -1 the total payload starting from @offset if subbuffered.
902 * Returns: A new buffer with the specified data of the payload.
905 gst_rtp_buffer_get_payload_subbuffer (GstRTPBuffer * rtp, guint offset,
910 plen = gst_rtp_buffer_get_payload_len (rtp);
911 /* we can't go past the length */
912 if (G_UNLIKELY (offset >= plen))
916 poffset = gst_rtp_buffer_get_header_len (rtp) + offset;
919 /* see if we need to shrink the buffer based on @len */
920 if (len != -1 && len < plen)
923 return gst_buffer_copy_region (rtp->buffer, GST_BUFFER_COPY_ALL, poffset,
929 g_warning ("offset=%u should be less then plen=%u", offset, plen);
935 * gst_rtp_buffer_get_payload_buffer:
936 * @rtp: the RTP packet
938 * Create a buffer of the payload of the RTP packet in @buffer. This function
939 * will internally create a subbuffer of @buffer so that a memcpy can be
942 * Returns: A new buffer with the data of the payload.
945 gst_rtp_buffer_get_payload_buffer (GstRTPBuffer * rtp)
947 return gst_rtp_buffer_get_payload_subbuffer (rtp, 0, -1);
951 * gst_rtp_buffer_get_payload_len:
952 * @rtp: the RTP packet
954 * Get the length of the payload of the RTP packet in @buffer.
956 * Returns: The length of the payload in @buffer.
959 gst_rtp_buffer_get_payload_len (GstRTPBuffer * rtp)
961 return gst_buffer_get_size (rtp->buffer) - gst_rtp_buffer_get_header_len (rtp)
966 * gst_rtp_buffer_get_payload:
967 * @rtp: the RTP packet
969 * Get a pointer to the payload data in @buffer. This pointer is valid as long
970 * as a reference to @buffer is held.
972 * Returns: (array) (element-type guint8) (transfer none): A pointer
973 * to the payload data in @buffer.
976 gst_rtp_buffer_get_payload (GstRTPBuffer * rtp)
985 hlen = gst_rtp_buffer_get_header_len (rtp);
986 plen = gst_buffer_get_size (rtp->buffer) - hlen - rtp->size[3];
988 if (!gst_buffer_find_memory (rtp->buffer, hlen, plen, &idx, &length, &skip))
991 if (!gst_buffer_map_range (rtp->buffer, idx, length, &rtp->map[2],
995 rtp->data[2] = rtp->map[2].data + skip;
1002 * gst_rtp_buffer_default_clock_rate:
1003 * @payload_type: the static payload type
1005 * Get the default clock-rate for the static payload type @payload_type.
1007 * Returns: the default clock rate or -1 if the payload type is not static or
1008 * the clock-rate is undefined.
1011 gst_rtp_buffer_default_clock_rate (guint8 payload_type)
1013 const GstRTPPayloadInfo *info;
1016 info = gst_rtp_payload_info_for_pt (payload_type);
1020 res = info->clock_rate;
1021 /* 0 means unknown so we have to return -1 from this function */
1029 * gst_rtp_buffer_compare_seqnum:
1030 * @seqnum1: a sequence number
1031 * @seqnum2: a sequence number
1033 * Compare two sequence numbers, taking care of wraparounds. This function
1034 * returns the difference between @seqnum1 and @seqnum2.
1036 * Returns: a negative value if @seqnum1 is bigger than @seqnum2, 0 if they
1037 * are equal or a positive value if @seqnum1 is smaller than @segnum2.
1040 gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2)
1042 return (gint16) (seqnum2 - seqnum1);
1046 * gst_rtp_buffer_ext_timestamp:
1047 * @exttimestamp: a previous extended timestamp
1048 * @timestamp: a new timestamp
1050 * Update the @exttimestamp field with @timestamp. For the first call of the
1051 * method, @exttimestamp should point to a location with a value of -1.
1053 * This function makes sure that the returned value is a constantly increasing
1054 * value even in the case where there is a timestamp wraparound.
1056 * Returns: The extended timestamp of @timestamp.
1059 gst_rtp_buffer_ext_timestamp (guint64 * exttimestamp, guint32 timestamp)
1061 guint64 result, diff, ext;
1063 g_return_val_if_fail (exttimestamp != NULL, -1);
1065 ext = *exttimestamp;
1070 /* pick wraparound counter from previous timestamp and add to new timestamp */
1071 result = timestamp + (ext & ~(G_GINT64_CONSTANT (0xffffffff)));
1073 /* check for timestamp wraparound */
1075 diff = ext - result;
1077 diff = result - ext;
1079 if (diff > G_MAXINT32) {
1080 /* timestamp went backwards more than allowed, we wrap around and get
1081 * updated extended timestamp. */
1082 result += (G_GINT64_CONSTANT (1) << 32);
1085 *exttimestamp = result;
1091 * gst_rtp_buffer_get_extension_onebyte_header:
1092 * @rtp: the RTP packet
1093 * @id: The ID of the header extension to be read (between 1 and 14).
1094 * @nth: Read the nth extension packet with the requested ID
1095 * @data: (out) (array length=size) (element-type guint8) (transfer none):
1097 * @size: (out): the size of the data in bytes
1099 * Parses RFC 5285 style header extensions with a one byte header. It will
1100 * return the nth extension with the requested id.
1102 * Returns: TRUE if @buffer had the requested header extension
1106 gst_rtp_buffer_get_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
1107 guint nth, gpointer * data, guint * size)
1115 g_return_val_if_fail (id > 0 && id < 15, FALSE);
1117 if (!gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer) & pdata,
1125 guint8 read_id, read_len;
1127 if (offset + 1 >= wordlen * 4)
1130 read_id = GST_READ_UINT8 (pdata + offset) >> 4;
1131 read_len = (GST_READ_UINT8 (pdata + offset) & 0x0F) + 1;
1134 /* ID 0 means its padding, skip */
1138 /* ID 15 is special and means we should stop parsing */
1142 /* Ignore extension headers where the size does not fit */
1143 if (offset + read_len > wordlen * 4)
1146 /* If we have the right one */
1147 if (id == read_id) {
1150 *data = pdata + offset;
1161 if (offset >= wordlen * 4)
1169 * gst_rtp_buffer_get_extension_twobytes_header:
1170 * @rtp: the RTP packet
1171 * @appbits: (out): Application specific bits
1172 * @id: The ID of the header extension to be read (between 1 and 14).
1173 * @nth: Read the nth extension packet with the requested ID
1174 * @data: (out) (array length=size) (element-type guint8) (transfer none):
1176 * @size: (out): the size of the data in bytes
1178 * Parses RFC 5285 style header extensions with a two bytes header. It will
1179 * return the nth extension with the requested id.
1181 * Returns: TRUE if @buffer had the requested header extension
1185 gst_rtp_buffer_get_extension_twobytes_header (GstRTPBuffer * rtp,
1186 guint8 * appbits, guint8 id, guint nth, gpointer * data, guint * size)
1189 guint8 *pdata = NULL;
1195 if (!gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer *) & pdata,
1199 if (bits >> 4 != 0x100)
1202 bytelen = wordlen * 4;
1205 guint8 read_id, read_len;
1207 if (offset + 2 >= bytelen)
1210 read_id = GST_READ_UINT8 (pdata + offset);
1216 read_len = GST_READ_UINT8 (pdata + offset);
1219 /* Ignore extension headers where the size does not fit */
1220 if (offset + read_len > bytelen)
1223 /* If we have the right one, return it */
1224 if (id == read_id) {
1227 *data = pdata + offset;
1245 get_onebyte_header_end_offset (guint8 * pdata, guint wordlen)
1248 guint bytelen = wordlen * 4;
1249 guint paddingcount = 0;
1251 while (offset + 1 < bytelen) {
1252 guint8 read_id, read_len;
1254 read_id = GST_READ_UINT8 (pdata + offset) >> 4;
1255 read_len = (GST_READ_UINT8 (pdata + offset) & 0x0F) + 1;
1258 /* ID 0 means its padding, skip */
1266 /* ID 15 is special and means we should stop parsing */
1267 /* It also means we can't add an extra packet */
1271 /* Ignore extension headers where the size does not fit */
1272 if (offset + read_len > bytelen)
1278 return offset - paddingcount;
1282 * gst_rtp_buffer_add_extension_onebyte_header:
1283 * @rtp: the RTP packet
1284 * @id: The ID of the header extension (between 1 and 14).
1285 * @data: (array length=size) (element-type guint8): location for data
1286 * @size: the size of the data in bytes
1288 * Adds a RFC 5285 header extension with a one byte header to the end of the
1289 * RTP header. If there is already a RFC 5285 header extension with a one byte
1290 * header, the new extension will be appended.
1291 * It will not work if there is already a header extension that does not follow
1292 * the mecanism described in RFC 5285 or if there is a header extension with
1293 * a two bytes header as described in RFC 5285. In that case, use
1294 * gst_rtp_buffer_add_extension_twobytes_header()
1296 * Returns: %TRUE if header extension could be added
1300 gst_rtp_buffer_add_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
1301 gpointer data, guint size)
1308 g_return_val_if_fail (id > 0 && id < 15, FALSE);
1309 g_return_val_if_fail (size >= 1 && size <= 16, FALSE);
1310 g_return_val_if_fail (gst_buffer_is_writable (rtp->buffer), FALSE);
1312 has_bit = gst_rtp_buffer_get_extension_data (rtp, &bits,
1313 (gpointer) & pdata, &wordlen);
1323 offset = get_onebyte_header_end_offset (pdata, wordlen);
1327 nextext = pdata + offset;
1328 offset = nextext - rtp->map[0].data;
1330 /* Don't add extra header if there isn't enough space */
1331 if (rtp->map[0].size < offset + size + 1)
1334 nextext[0] = (id << 4) | (0x0F & (size - 1));
1335 memcpy (nextext + 1, data, size);
1337 extlen = nextext - pdata + size + 1;
1339 wordlen = extlen / 4 + 1;
1340 memset (nextext + size + 1, 0, 4 - extlen % 4);
1342 wordlen = extlen / 4;
1345 gst_rtp_buffer_set_extension_data (rtp, 0xBEDE, wordlen);
1347 wordlen = (size + 1) / 4 + (((size + 1) % 4) ? 1 : 0);
1349 gst_rtp_buffer_set_extension_data (rtp, 0xBEDE, wordlen);
1351 gst_rtp_buffer_get_extension_data (rtp, &bits,
1352 (gpointer) & pdata, &wordlen);
1354 pdata[0] = (id << 4) | (0x0F & (size - 1));
1355 memcpy (pdata + 1, data, size);
1358 memset (pdata + size + 1, 0, 4 - ((size + 1) % 4));
1366 get_twobytes_header_end_offset (guint8 * pdata, guint wordlen)
1369 guint bytelen = wordlen * 4;
1370 guint paddingcount = 0;
1372 while (offset + 2 < bytelen) {
1373 guint8 read_id, read_len;
1375 read_id = GST_READ_UINT8 (pdata + offset);
1378 /* ID 0 means its padding, skip */
1386 read_len = GST_READ_UINT8 (pdata + offset);
1389 /* Ignore extension headers where the size does not fit */
1390 if (offset + read_len > bytelen)
1396 return offset - paddingcount;
1400 * gst_rtp_buffer_add_extension_twobytes_header:
1401 * @rtp: the RTP packet
1402 * @appbits: Application specific bits
1403 * @id: The ID of the header extension
1404 * @data: (array length=size) (element-type guint8): location for data
1405 * @size: the size of the data in bytes
1407 * Adds a RFC 5285 header extension with a two bytes header to the end of the
1408 * RTP header. If there is already a RFC 5285 header extension with a two bytes
1409 * header, the new extension will be appended.
1410 * It will not work if there is already a header extension that does not follow
1411 * the mecanism described in RFC 5285 or if there is a header extension with
1412 * a one byte header as described in RFC 5285. In that case, use
1413 * gst_rtp_buffer_add_extension_onebyte_header()
1415 * Returns: %TRUE if header extension could be added
1419 gst_rtp_buffer_add_extension_twobytes_header (GstRTPBuffer * rtp,
1420 guint8 appbits, guint8 id, gpointer data, guint size)
1427 g_return_val_if_fail ((appbits & 0xF0) == 0, FALSE);
1428 g_return_val_if_fail (size < 256, FALSE);
1429 g_return_val_if_fail (gst_buffer_is_writable (rtp->buffer), FALSE);
1431 has_bit = gst_rtp_buffer_get_extension_data (rtp, &bits,
1432 (gpointer) & pdata, &wordlen);
1439 if (bits != ((0x100 << 4) | (appbits & 0x0f)))
1442 offset = get_twobytes_header_end_offset (pdata, wordlen);
1444 nextext = pdata + offset;
1446 offset = nextext - rtp->map[0].data;
1448 /* Don't add extra header if there isn't enough space */
1449 if (rtp->map[0].size < offset + size + 2)
1454 memcpy (nextext + 2, data, size);
1456 extlen = nextext - pdata + size + 2;
1458 wordlen = extlen / 4 + 1;
1459 memset (nextext + size + 2, 0, 4 - extlen % 4);
1461 wordlen = extlen / 4;
1464 gst_rtp_buffer_set_extension_data (rtp, (0x100 << 4) | (appbits & 0x0F),
1467 wordlen = (size + 2) / 4 + (((size + 2) % 4) ? 1 : 0);
1469 gst_rtp_buffer_set_extension_data (rtp, (0x100 << 4) | (appbits & 0x0F),
1472 gst_rtp_buffer_get_extension_data (rtp, &bits,
1473 (gpointer) & pdata, &wordlen);
1477 memcpy (pdata + 2, data, size);
1479 memset (pdata + size + 2, 0, 4 - ((size + 2) % 4));