rtp: Remove unused variables
[platform/upstream/gstreamer.git] / gst-libs / gst / rtp / gstrtpbuffer.c
1 /* GStreamer
2  * Copyright (C) <2005> Philippe Khalaf <burger@speedy.org>
3  * Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 /**
22  * SECTION:gstrtpbuffer
23  * @short_description: Helper methods for dealing with RTP buffers
24  * @see_also: #GstBaseRTPPayload, #GstBaseRTPDepayload, gstrtcpbuffer
25  *
26  * <refsect2>
27  * <para>
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.
31  * </para>
32  * </refsect2>
33  *
34  * Last reviewed on 2006-07-17 (0.10.10)
35  */
36
37 #include "gstrtpbuffer.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41
42 #define GST_RTP_HEADER_LEN 12
43
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
46  */
47 typedef struct _GstRTPHeader
48 {
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 */
63 #else
64 #error "G_BYTE_ORDER should be big or little endian."
65 #endif
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 */
70 } GstRTPHeader;
71
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))
85
86 /**
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
92  *
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  * MALLOCDATA of @buffer will be overwritten and will not be freed. 
96  * All other RTP header fields will be set to 0/FALSE.
97  */
98 void
99 gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
100     guint8 pad_len, guint8 csrc_count)
101 {
102   guint len;
103   guint8 *data;
104
105   g_return_if_fail (csrc_count <= 15);
106   g_return_if_fail (GST_IS_BUFFER (buffer));
107
108   len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
109       + payload_len + pad_len;
110
111   data = g_malloc (len);
112   GST_BUFFER_MALLOCDATA (buffer) = data;
113   GST_BUFFER_DATA (buffer) = data;
114   GST_BUFFER_SIZE (buffer) = len;
115
116   /* fill in defaults */
117   GST_RTP_HEADER_VERSION (data) = GST_RTP_VERSION;
118   GST_RTP_HEADER_PADDING (data) = FALSE;
119   GST_RTP_HEADER_EXTENSION (data) = FALSE;
120   GST_RTP_HEADER_CSRC_COUNT (data) = csrc_count;
121   memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, 0), 0,
122       csrc_count * sizeof (guint32));
123   GST_RTP_HEADER_MARKER (data) = FALSE;
124   GST_RTP_HEADER_PAYLOAD_TYPE (data) = 0;
125   GST_RTP_HEADER_SEQ (data) = 0;
126   GST_RTP_HEADER_TIMESTAMP (data) = 0;
127   GST_RTP_HEADER_SSRC (data) = 0;
128 }
129
130 /**
131  * gst_rtp_buffer_new_take_data:
132  * @data: data for the new buffer
133  * @len: the length of data
134  *
135  * Create a new buffer and set the data and size of the buffer to @data and @len
136  * respectively. @data will be freed when the buffer is unreffed, so this
137  * function transfers ownership of @data to the new buffer.
138  *
139  * Returns: A newly allocated buffer with @data and of size @len.
140  */
141 GstBuffer *
142 gst_rtp_buffer_new_take_data (gpointer data, guint len)
143 {
144   GstBuffer *result;
145
146   g_return_val_if_fail (data != NULL, NULL);
147   g_return_val_if_fail (len > 0, NULL);
148
149   result = gst_buffer_new ();
150
151   GST_BUFFER_MALLOCDATA (result) = data;
152   GST_BUFFER_DATA (result) = data;
153   GST_BUFFER_SIZE (result) = len;
154
155   return result;
156 }
157
158 /**
159  * gst_rtp_buffer_new_copy_data:
160  * @data: data for the new buffer
161  * @len: the length of data
162  *
163  * Create a new buffer and set the data to a copy of @len
164  * bytes of @data and the size to @len. The data will be freed when the buffer
165  * is freed.
166  *
167  * Returns: A newly allocated buffer with a copy of @data and of size @len.
168  */
169 GstBuffer *
170 gst_rtp_buffer_new_copy_data (gpointer data, guint len)
171 {
172   return gst_rtp_buffer_new_take_data (g_memdup (data, len), len);
173 }
174
175 /**
176  * gst_rtp_buffer_new_allocate:
177  * @payload_len: the length of the payload
178  * @pad_len: the amount of padding
179  * @csrc_count: the number of CSRC entries
180  *
181  * Allocate a new #GstBuffer with enough data to hold an RTP packet with
182  * @csrc_count CSRCs, a payload length of @payload_len and padding of @pad_len.
183  * All other RTP header fields will be set to 0/FALSE.
184  *
185  * Returns: A newly allocated buffer that can hold an RTP packet with given
186  * parameters.
187  */
188 GstBuffer *
189 gst_rtp_buffer_new_allocate (guint payload_len, guint8 pad_len,
190     guint8 csrc_count)
191 {
192   GstBuffer *result;
193
194   g_return_val_if_fail (csrc_count <= 15, NULL);
195
196   result = gst_buffer_new ();
197   gst_rtp_buffer_allocate_data (result, payload_len, pad_len, csrc_count);
198
199   return result;
200 }
201
202 /**
203  * gst_rtp_buffer_new_allocate_len:
204  * @packet_len: the total length of the packet
205  * @pad_len: the amount of padding
206  * @csrc_count: the number of CSRC entries
207  *
208  * Create a new #GstBuffer that can hold an RTP packet that is exactly
209  * @packet_len long. The length of the payload depends on @pad_len and
210  * @csrc_count and can be calculated with gst_rtp_buffer_calc_payload_len().
211  * All RTP header fields will be set to 0/FALSE.
212  *
213  * Returns: A newly allocated buffer that can hold an RTP packet of @packet_len.
214  */
215 GstBuffer *
216 gst_rtp_buffer_new_allocate_len (guint packet_len, guint8 pad_len,
217     guint8 csrc_count)
218 {
219   guint len;
220
221   g_return_val_if_fail (csrc_count <= 15, NULL);
222
223   len = gst_rtp_buffer_calc_payload_len (packet_len, pad_len, csrc_count);
224
225   return gst_rtp_buffer_new_allocate (len, pad_len, csrc_count);
226 }
227
228 /**
229  * gst_rtp_buffer_calc_header_len:
230  * @csrc_count: the number of CSRC entries
231  *
232  * Calculate the header length of an RTP packet with @csrc_count CSRC entries.
233  * An RTP packet can have at most 15 CSRC entries.
234  *
235  * Returns: The length of an RTP header with @csrc_count CSRC entries.
236  */
237 guint
238 gst_rtp_buffer_calc_header_len (guint8 csrc_count)
239 {
240   g_return_val_if_fail (csrc_count <= 15, 0);
241
242   return GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32));
243 }
244
245 /**
246  * gst_rtp_buffer_calc_packet_len:
247  * @payload_len: the length of the payload
248  * @pad_len: the amount of padding
249  * @csrc_count: the number of CSRC entries
250  *
251  * Calculate the total length of an RTP packet with a payload size of @payload_len,
252  * a padding of @pad_len and a @csrc_count CSRC entries.
253  *
254  * Returns: The total length of an RTP header with given parameters.
255  */
256 guint
257 gst_rtp_buffer_calc_packet_len (guint payload_len, guint8 pad_len,
258     guint8 csrc_count)
259 {
260   g_return_val_if_fail (csrc_count <= 15, 0);
261
262   return payload_len + GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32))
263       + pad_len;
264 }
265
266 /**
267  * gst_rtp_buffer_calc_payload_len:
268  * @packet_len: the length of the total RTP packet
269  * @pad_len: the amount of padding
270  * @csrc_count: the number of CSRC entries
271  *
272  * Calculate the length of the payload of an RTP packet with size @packet_len,
273  * a padding of @pad_len and a @csrc_count CSRC entries.
274  *
275  * Returns: The length of the payload of an RTP packet  with given parameters.
276  */
277 guint
278 gst_rtp_buffer_calc_payload_len (guint packet_len, guint8 pad_len,
279     guint8 csrc_count)
280 {
281   g_return_val_if_fail (csrc_count <= 15, 0);
282
283   return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32))
284       - pad_len;
285 }
286
287 /**
288  * validate_data:
289  * @data: the data to validate
290  * @len: the length of @data to validate
291  * @payload: the payload if @data represents the header only
292  * @payload_len: the len of the payload
293  *
294  * Checks if @data is a valid RTP packet.
295  *
296  * Returns: TRUE if @data is a valid RTP packet
297  */
298 static gboolean
299 validate_data (guint8 * data, guint len, guint8 * payload, guint payload_len)
300 {
301   guint8 padding;
302   guint8 csrc_count;
303   guint header_len;
304   guint8 version;
305
306   g_return_val_if_fail (data != NULL, FALSE);
307
308   header_len = GST_RTP_HEADER_LEN;
309   if (G_UNLIKELY (len < header_len))
310     goto wrong_length;
311
312   /* check version */
313   version = (data[0] & 0xc0);
314   if (G_UNLIKELY (version != (GST_RTP_VERSION << 6)))
315     goto wrong_version;
316
317   /* calc header length with csrc */
318   csrc_count = (data[0] & 0x0f);
319   header_len += csrc_count * sizeof (guint32);
320
321   /* calc extension length when present. */
322   if (data[0] & 0x10) {
323     guint8 *extpos;
324     guint16 extlen;
325
326     /* this points to the extenstion bits and header length */
327     extpos = &data[header_len];
328
329     /* skip the header and check that we have enough space */
330     header_len += 4;
331     if (G_UNLIKELY (len < header_len))
332       goto wrong_length;
333
334     /* skip id */
335     extpos += 2;
336     /* read length as the number of 32 bits words */
337     extlen = GST_READ_UINT16_BE (extpos);
338
339     header_len += extlen * sizeof (guint32);
340   }
341
342   /* check for padding */
343   if (data[0] & 0x20) {
344     if (payload)
345       padding = payload[payload_len - 1];
346     else
347       padding = data[len - 1];
348   } else {
349     padding = 0;
350   }
351
352   /* check if padding and header not bigger than packet length */
353   if (G_UNLIKELY (len < padding + header_len))
354     goto wrong_padding;
355
356   return TRUE;
357
358   /* ERRORS */
359 wrong_length:
360   {
361     GST_DEBUG ("len < header_len check failed (%d < %d)", len, header_len);
362     goto dump_packet;
363   }
364 wrong_version:
365   {
366     GST_DEBUG ("version check failed (%d != %d)", version, GST_RTP_VERSION);
367     goto dump_packet;
368   }
369 wrong_padding:
370   {
371     GST_DEBUG ("padding check failed (%d - %d < %d)", len, header_len, padding);
372     goto dump_packet;
373   }
374 dump_packet:
375   {
376     GST_MEMDUMP ("buffer", data, len);
377     return FALSE;
378   }
379 }
380
381 /**
382  * gst_rtp_buffer_validate_data:
383  * @data: the data to validate
384  * @len: the length of @data to validate
385  *
386  * Check if the @data and @size point to the data of a valid RTP packet.
387  * This function checks the length, version and padding of the packet data.
388  * Use this function to validate a packet before using the other functions in
389  * this module.
390  *
391  * Returns: TRUE if the data points to a valid RTP packet.
392  */
393 gboolean
394 gst_rtp_buffer_validate_data (guint8 * data, guint len)
395 {
396   return validate_data (data, len, NULL, 0);
397 }
398
399 /**
400  * gst_rtp_buffer_validate:
401  * @buffer: the buffer to validate
402  *
403  * Check if the data pointed to by @buffer is a valid RTP packet using
404  * validate_data().
405  * Use this function to validate a packet before using the other functions in
406  * this module.
407  *
408  * Returns: TRUE if @buffer is a valid RTP packet.
409  */
410 gboolean
411 gst_rtp_buffer_validate (GstBuffer * buffer)
412 {
413   guint8 *data;
414   guint len;
415
416   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
417
418   data = GST_BUFFER_DATA (buffer);
419   len = GST_BUFFER_SIZE (buffer);
420
421   return validate_data (data, len, NULL, 0);
422 }
423
424 /**
425  * gst_rtp_buffer_list_validate:
426  * @list: the buffer list to validate
427  *
428  * Check if all RTP packets in the @list are valid using validate_data().
429  * Use this function to validate an list before using the other functions in
430  * this module.
431  *
432  * Returns: TRUE if @list consists only of valid RTP packets.
433  *
434  * Since: 0.10.24
435  */
436 gboolean
437 gst_rtp_buffer_list_validate (GstBufferList * list)
438 {
439   guint16 prev_seqnum = 0;
440   GstBufferListIterator *it;
441   guint i = 0;
442
443   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);
444
445   it = gst_buffer_list_iterate (list);
446   g_return_val_if_fail (it != NULL, FALSE);
447
448   /* iterate through all the RTP packets in the list */
449   while (gst_buffer_list_iterator_next_group (it)) {
450     GstBuffer *rtpbuf;
451     GstBuffer *paybuf;
452     guint8 *packet_header;
453     guint8 *packet_payload;
454     guint payload_size;
455     guint packet_size;
456     guint j, n_buffers;
457
458     /* each group should consists of at least 1 buffer: The first buffer always
459      * contains the complete RTP header. Next buffers contain the payload */
460     n_buffers = gst_buffer_list_iterator_n_buffers (it);
461     if (n_buffers < 1)
462       goto invalid_list;
463
464     /* get the RTP header (and if n_buffers == 1 also the payload) */
465     rtpbuf = gst_buffer_list_iterator_next (it);
466     packet_header = GST_BUFFER_DATA (rtpbuf);
467     if (packet_header == NULL)
468       goto invalid_list;
469
470     /* check the sequence number */
471     if (G_UNLIKELY (i == 0)) {
472       prev_seqnum = g_ntohs (GST_RTP_HEADER_SEQ (packet_header));
473       i++;
474     } else {
475       if (++prev_seqnum != g_ntohs (GST_RTP_HEADER_SEQ (packet_header)))
476         goto invalid_list;
477     }
478
479     packet_size = GST_BUFFER_SIZE (rtpbuf);
480     packet_payload = NULL;
481     payload_size = 0;
482
483     /* get the payload buffers */
484     for (j = 1; j < n_buffers; j++) {
485       /* get the payload */
486       paybuf = gst_buffer_list_iterator_next (it);
487
488       if ((packet_payload = GST_BUFFER_DATA (paybuf)) == NULL)
489         goto invalid_list;
490
491       if ((payload_size = GST_BUFFER_SIZE (paybuf)) == 0)
492         goto invalid_list;
493
494       /* the size of the RTP packet within the current group */
495       packet_size += payload_size;
496     }
497
498     /* validate packet */
499     if (!validate_data (packet_header, packet_size, packet_payload,
500             payload_size)) {
501       goto invalid_list;
502     }
503   }
504
505   gst_buffer_list_iterator_free (it);
506
507   return TRUE;
508
509   /* ERRORS */
510 invalid_list:
511   {
512     gst_buffer_list_iterator_free (it);
513     return FALSE;
514   }
515 }
516
517 /**
518  * gst_rtp_buffer_set_packet_len:
519  * @buffer: the buffer
520  * @len: the new packet length
521  *
522  * Set the total @buffer size to @len. The data in the buffer will be made
523  * larger if needed. Any padding will be removed from the packet. 
524  */
525 void
526 gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len)
527 {
528   guint oldlen;
529   guint8 *data;
530
531   oldlen = GST_BUFFER_SIZE (buffer);
532   data = GST_BUFFER_DATA (buffer);
533
534   if (oldlen < len) {
535     data = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len);
536     GST_BUFFER_MALLOCDATA (buffer) = data;
537     GST_BUFFER_DATA (buffer) = data;
538   }
539   GST_BUFFER_SIZE (buffer) = len;
540
541   /* remove any padding */
542   GST_RTP_HEADER_PADDING (data) = FALSE;
543 }
544
545 /**
546  * gst_rtp_buffer_get_packet_len:
547  * @buffer: the buffer
548  *
549  * Return the total length of the packet in @buffer.
550  *
551  * Returns: The total length of the packet in @buffer.
552  */
553 guint
554 gst_rtp_buffer_get_packet_len (GstBuffer * buffer)
555 {
556   return GST_BUFFER_SIZE (buffer);
557 }
558
559 /**
560  * gst_rtp_buffer_get_header_len:
561  * @buffer: the buffer
562  *
563  * Return the total length of the header in @buffer. This include the length of
564  * the fixed header, the CSRC list and the extension header.
565  *
566  * Returns: The total length of the header in @buffer.
567  */
568 guint
569 gst_rtp_buffer_get_header_len (GstBuffer * buffer)
570 {
571   guint len;
572   guint8 *data;
573
574   data = GST_BUFFER_DATA (buffer);
575
576   len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
577   if (GST_RTP_HEADER_EXTENSION (data))
578     len += GST_READ_UINT16_BE (data + len + 2) * 4 + 4;
579
580   return len;
581 }
582
583 /**
584  * gst_rtp_buffer_get_version:
585  * @buffer: the buffer
586  *
587  * Get the version number of the RTP packet in @buffer.
588  *
589  * Returns: The version of @buffer.
590  */
591 guint8
592 gst_rtp_buffer_get_version (GstBuffer * buffer)
593 {
594   return GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer));
595 }
596
597 /**
598  * gst_rtp_buffer_set_version:
599  * @buffer: the buffer
600  * @version: the new version
601  *
602  * Set the version of the RTP packet in @buffer to @version.
603  */
604 void
605 gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version)
606 {
607   g_return_if_fail (version < 0x04);
608
609   GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer)) = version;
610 }
611
612 /**
613  * gst_rtp_buffer_get_padding:
614  * @buffer: the buffer
615  *
616  * Check if the padding bit is set on the RTP packet in @buffer.
617  *
618  * Returns: TRUE if @buffer has the padding bit set.
619  */
620 gboolean
621 gst_rtp_buffer_get_padding (GstBuffer * buffer)
622 {
623   return GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer));
624 }
625
626 /**
627  * gst_rtp_buffer_set_padding:
628  * @buffer: the buffer
629  * @padding: the new padding
630  *
631  * Set the padding bit on the RTP packet in @buffer to @padding.
632  */
633 void
634 gst_rtp_buffer_set_padding (GstBuffer * buffer, gboolean padding)
635 {
636   GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer)) = padding;
637 }
638
639 /**
640  * gst_rtp_buffer_pad_to:
641  * @buffer: the buffer
642  * @len: the new amount of padding
643  *
644  * Set the amount of padding in the RTP packet in @buffer to
645  * @len. If @len is 0, the padding is removed.
646  *
647  * NOTE: This function does not work correctly.
648  */
649 void
650 gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len)
651 {
652   guint8 *data;
653
654   data = GST_BUFFER_DATA (buffer);
655
656   if (len > 0)
657     GST_RTP_HEADER_PADDING (data) = TRUE;
658   else
659     GST_RTP_HEADER_PADDING (data) = FALSE;
660
661   /* FIXME, set the padding byte at the end of the payload data */
662 }
663
664 /**
665  * gst_rtp_buffer_get_extension:
666  * @buffer: the buffer
667  *
668  * Check if the extension bit is set on the RTP packet in @buffer.
669  * 
670  * Returns: TRUE if @buffer has the extension bit set.
671  */
672 gboolean
673 gst_rtp_buffer_get_extension (GstBuffer * buffer)
674 {
675   return GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer));
676 }
677
678 /**
679  * gst_rtp_buffer_set_extension:
680  * @buffer: the buffer
681  * @extension: the new extension
682  *
683  * Set the extension bit on the RTP packet in @buffer to @extension.
684  */
685 void
686 gst_rtp_buffer_set_extension (GstBuffer * buffer, gboolean extension)
687 {
688   GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer)) = extension;
689 }
690
691 /**
692  * gst_rtp_buffer_get_extension_data:
693  * @buffer: the buffer
694  * @bits: location for result bits
695  * @data: location for data
696  * @wordlen: location for length of @data in 32 bits words
697  *
698  * Get the extension data. @bits will contain the extension 16 bits of custom
699  * data. @data will point to the data in the extension and @wordlen will contain
700  * the length of @data in 32 bits words.
701  *
702  * If @buffer did not contain an extension, this function will return %FALSE
703  * with @bits, @data and @wordlen unchanged.
704  * 
705  * Returns: TRUE if @buffer had the extension bit set.
706  *
707  * Since: 0.10.15
708  */
709 gboolean
710 gst_rtp_buffer_get_extension_data (GstBuffer * buffer, guint16 * bits,
711     gpointer * data, guint * wordlen)
712 {
713   guint len;
714   guint8 *pdata;
715
716   pdata = GST_BUFFER_DATA (buffer);
717
718   if (!GST_RTP_HEADER_EXTENSION (pdata))
719     return FALSE;
720
721   /* move to the extension */
722   len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (pdata);
723   pdata += len;
724
725   if (bits)
726     *bits = GST_READ_UINT16_BE (pdata);
727   if (wordlen)
728     *wordlen = GST_READ_UINT16_BE (pdata + 2);
729   if (data)
730     *data = pdata + 4;
731
732   return TRUE;
733 }
734
735 /**
736  * gst_rtp_buffer_set_extension_data:
737  * @buffer: the buffer
738  * @bits: the bits specific for the extension
739  * @length: the length that counts the number of 32-bit words in
740  * the extension, excluding the extension header ( therefore zero is a valid length)
741  *
742  * Set the extension bit of the rtp buffer and fill in the @bits and @length of the
743  * extension header. It will refuse to set the extension data if the buffer is not
744  * large enough.
745  *
746  * Returns: True if done.
747  *
748  * Since: 0.10.18
749  */
750 gboolean
751 gst_rtp_buffer_set_extension_data (GstBuffer * buffer, guint16 bits,
752     guint16 length)
753 {
754   guint32 min_size = 0;
755   guint8 *data;
756
757   data = GST_BUFFER_DATA (buffer);
758
759   /* check if the buffer is big enough to hold the extension */
760   min_size =
761       GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data) + 4 +
762       length * sizeof (guint32);
763   if (G_UNLIKELY (min_size > GST_BUFFER_SIZE (buffer)))
764     goto too_small;
765
766   /* now we can set the extension bit */
767   gst_rtp_buffer_set_extension (buffer, TRUE);
768
769   data += GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
770   GST_WRITE_UINT16_BE (data, bits);
771   GST_WRITE_UINT16_BE (data + 2, length);
772
773   return TRUE;
774
775   /* ERRORS */
776 too_small:
777   {
778     g_warning
779         ("rtp buffer too small: need more than %d bytes but only have %d bytes",
780         min_size, GST_BUFFER_SIZE (buffer));
781     return FALSE;
782   }
783 }
784
785 /**
786  * gst_rtp_buffer_get_ssrc:
787  * @buffer: the buffer
788  *
789  * Get the SSRC of the RTP packet in @buffer.
790  * 
791  * Returns: the SSRC of @buffer in host order.
792  */
793 guint32
794 gst_rtp_buffer_get_ssrc (GstBuffer * buffer)
795 {
796   return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)));
797 }
798
799 /**
800  * gst_rtp_buffer_list_get_ssrc:
801  * @list: the buffer list
802  *
803  * Get the SSRC of the first RTP packet in @list.
804  * All RTP packets within @list have the same SSRC.
805  *
806  * Returns: the SSRC of @list in host order.
807  *
808  * Since: 0.10.24
809  */
810 guint32
811 gst_rtp_buffer_list_get_ssrc (GstBufferList * list)
812 {
813   GstBuffer *buffer;
814
815   buffer = gst_buffer_list_get (list, 0, 0);
816   g_return_val_if_fail (buffer != NULL, 0);
817
818   return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)));
819 }
820
821 /**
822  * gst_rtp_buffer_set_ssrc:
823  * @buffer: the buffer
824  * @ssrc: the new SSRC
825  *
826  * Set the SSRC on the RTP packet in @buffer to @ssrc.
827  */
828 void
829 gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc)
830 {
831   GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)) = g_htonl (ssrc);
832 }
833
834 static GstBufferListItem
835 set_ssrc_header (GstBuffer ** buffer, guint group, guint idx, guint32 * ssrc)
836 {
837   GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (*buffer)) = g_htonl (*ssrc);
838   return GST_BUFFER_LIST_SKIP_GROUP;
839 }
840
841 /**
842  * gst_rtp_buffer_list_set_ssrc:
843  * @list: the buffer list
844  * @ssrc: the new SSRC
845  *
846  * Set the SSRC on each RTP packet in @list to @ssrc.
847  *
848  * Since: 0.10.24
849  */
850 void
851 gst_rtp_buffer_list_set_ssrc (GstBufferList * list, guint32 ssrc)
852 {
853   gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc_header, &ssrc);
854 }
855
856 /**
857  * gst_rtp_buffer_get_csrc_count:
858  * @buffer: the buffer
859  *
860  * Get the CSRC count of the RTP packet in @buffer.
861  * 
862  * Returns: the CSRC count of @buffer.
863  */
864 guint8
865 gst_rtp_buffer_get_csrc_count (GstBuffer * buffer)
866 {
867   return GST_RTP_HEADER_CSRC_COUNT (GST_BUFFER_DATA (buffer));
868 }
869
870 /**
871  * gst_rtp_buffer_get_csrc:
872  * @buffer: the buffer
873  * @idx: the index of the CSRC to get
874  *
875  * Get the CSRC at index @idx in @buffer.
876  * 
877  * Returns: the CSRC at index @idx in host order.
878  */
879 guint32
880 gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx)
881 {
882   guint8 *data;
883
884   data = GST_BUFFER_DATA (buffer);
885
886   g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data), 0);
887
888   return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx));
889 }
890
891 /**
892  * gst_rtp_buffer_set_csrc:
893  * @buffer: the buffer
894  * @idx: the CSRC index to set
895  * @csrc: the CSRC in host order to set at @idx
896  *
897  * Modify the CSRC at index @idx in @buffer to @csrc.
898  */
899 void
900 gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc)
901 {
902   guint8 *data;
903
904   data = GST_BUFFER_DATA (buffer);
905
906   g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data));
907
908   GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx), csrc);
909 }
910
911 /**
912  * gst_rtp_buffer_get_marker:
913  * @buffer: the buffer
914  *
915  * Check if the marker bit is set on the RTP packet in @buffer.
916  *
917  * Returns: TRUE if @buffer has the marker bit set.
918  */
919 gboolean
920 gst_rtp_buffer_get_marker (GstBuffer * buffer)
921 {
922   return GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer));
923 }
924
925 /**
926  * gst_rtp_buffer_set_marker:
927  * @buffer: the buffer
928  * @marker: the new marker
929  *
930  * Set the marker bit on the RTP packet in @buffer to @marker.
931  */
932 void
933 gst_rtp_buffer_set_marker (GstBuffer * buffer, gboolean marker)
934 {
935   GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer)) = marker;
936 }
937
938 /**
939  * gst_rtp_buffer_get_payload_type:
940  * @buffer: the buffer
941  *
942  * Get the payload type of the RTP packet in @buffer.
943  *
944  * Returns: The payload type.
945  */
946 guint8
947 gst_rtp_buffer_get_payload_type (GstBuffer * buffer)
948 {
949   return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer));
950 }
951
952 /**
953  * gst_rtp_buffer_list_get_payload_type:
954  * @list: the buffer list
955  *
956  * Get the payload type of the first RTP packet in @list.
957  * All packets in @list should have the same payload type.
958  *
959  * Returns: The payload type.
960  *
961  * Since: 0.10.24
962  */
963 guint8
964 gst_rtp_buffer_list_get_payload_type (GstBufferList * list)
965 {
966   GstBuffer *buffer;
967
968   buffer = gst_buffer_list_get (list, 0, 0);
969   g_return_val_if_fail (buffer != NULL, 0);
970
971   return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer));
972 }
973
974 /**
975  * gst_rtp_buffer_set_payload_type:
976  * @buffer: the buffer
977  * @payload_type: the new type
978  *
979  * Set the payload type of the RTP packet in @buffer to @payload_type.
980  */
981 void
982 gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type)
983 {
984   g_return_if_fail (payload_type < 0x80);
985
986   GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer)) = payload_type;
987 }
988
989 static GstBufferListItem
990 set_pt_header (GstBuffer ** buffer, guint group, guint idx, guint8 * pt)
991 {
992   GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (*buffer)) = *pt;
993   return GST_BUFFER_LIST_SKIP_GROUP;
994 }
995
996 /**
997  * gst_rtp_buffer_list_set_payload_type:
998  * @list: the buffer list
999  * @payload_type: the new type
1000  *
1001  * Set the payload type of each RTP packet in @list to @payload_type.
1002  *
1003  * Since: 0.10.24
1004  */
1005 void
1006 gst_rtp_buffer_list_set_payload_type (GstBufferList * list, guint8 payload_type)
1007 {
1008   g_return_if_fail (payload_type < 0x80);
1009
1010   gst_buffer_list_foreach (list, (GstBufferListFunc) set_pt_header,
1011       &payload_type);
1012 }
1013
1014 /**
1015  * gst_rtp_buffer_get_seq:
1016  * @buffer: the buffer
1017  *
1018  * Get the sequence number of the RTP packet in @buffer.
1019  *
1020  * Returns: The sequence number in host order.
1021  */
1022 guint16
1023 gst_rtp_buffer_get_seq (GstBuffer * buffer)
1024 {
1025   return g_ntohs (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)));
1026 }
1027
1028 /**
1029  * gst_rtp_buffer_set_seq:
1030  * @buffer: the buffer
1031  * @seq: the new sequence number
1032  *
1033  * Set the sequence number of the RTP packet in @buffer to @seq.
1034  */
1035 void
1036 gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq)
1037 {
1038   GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)) = g_htons (seq);
1039 }
1040
1041 static GstBufferListItem
1042 set_seq_header (GstBuffer ** buffer, guint group, guint idx, guint16 * seq)
1043 {
1044   GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (*buffer)) = g_htons (*seq);
1045   (*seq)++;
1046   return GST_BUFFER_LIST_SKIP_GROUP;
1047 }
1048
1049 /**
1050  * gst_rtp_buffer_list_set_seq:
1051  * @list: the buffer list
1052  * @seq: the new sequence number
1053  *
1054  * Set the sequence number of each RTP packet in @list to @seq.
1055  *
1056  * Returns: The seq number of the last packet in the list + 1.
1057  *
1058  * Since: 0.10.24
1059  */
1060 guint16
1061 gst_rtp_buffer_list_set_seq (GstBufferList * list, guint16 seq)
1062 {
1063   gst_buffer_list_foreach (list, (GstBufferListFunc) set_seq_header, &seq);
1064   return seq;
1065 }
1066
1067 /**
1068  * gst_rtp_buffer_list_get_seq:
1069  * @list: the buffer list
1070  *
1071  * Get the sequence number of the first RTP packet in @list.
1072  * All packets within @list have the same sequence number.
1073  *
1074  * Returns: The seq number
1075  *
1076  * Since: 0.10.24
1077  */
1078 guint16
1079 gst_rtp_buffer_list_get_seq (GstBufferList * list)
1080 {
1081   GstBuffer *buffer;
1082
1083   buffer = gst_buffer_list_get (list, 0, 0);
1084   g_return_val_if_fail (buffer != NULL, 0);
1085
1086   return g_ntohl (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)));
1087 }
1088
1089
1090 /**
1091  * gst_rtp_buffer_get_timestamp:
1092  * @buffer: the buffer
1093  *
1094  * Get the timestamp of the RTP packet in @buffer.
1095  *
1096  * Returns: The timestamp in host order.
1097  */
1098 guint32
1099 gst_rtp_buffer_get_timestamp (GstBuffer * buffer)
1100 {
1101   return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)));
1102 }
1103
1104 /**
1105  * gst_rtp_buffer_list_get_timestamp:
1106  * @list: the buffer list
1107  *
1108  * Get the timestamp of the first RTP packet in @list.
1109  * All packets within @list have the same timestamp.
1110  *
1111  * Returns: The timestamp in host order.
1112  *
1113  * Since: 0.10.24
1114  */
1115 guint32
1116 gst_rtp_buffer_list_get_timestamp (GstBufferList * list)
1117 {
1118   GstBuffer *buffer;
1119
1120   buffer = gst_buffer_list_get (list, 0, 0);
1121   g_return_val_if_fail (buffer != NULL, 0);
1122
1123   return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)));
1124 }
1125
1126 /**
1127  * gst_rtp_buffer_set_timestamp:
1128  * @buffer: the buffer
1129  * @timestamp: the new timestamp
1130  *
1131  * Set the timestamp of the RTP packet in @buffer to @timestamp.
1132  */
1133 void
1134 gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp)
1135 {
1136   GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)) = g_htonl (timestamp);
1137 }
1138
1139
1140 static GstBufferListItem
1141 set_timestamp_header (GstBuffer ** buffer, guint group, guint idx,
1142     guint32 * timestamp)
1143 {
1144   GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (*buffer)) = g_htonl (*timestamp);
1145   return GST_BUFFER_LIST_SKIP_GROUP;
1146 }
1147
1148 /**
1149  * gst_rtp_buffer_list_set_timestamp:
1150  * @list: the buffer list
1151  * @timestamp: the new timestamp
1152  *
1153  * Set the timestamp of each RTP packet in @list to @timestamp.
1154  *
1155  * Since: 0.10.24
1156  */
1157 void
1158 gst_rtp_buffer_list_set_timestamp (GstBufferList * list, guint32 timestamp)
1159 {
1160   gst_buffer_list_foreach (list, (GstBufferListFunc) set_timestamp_header,
1161       &timestamp);
1162 }
1163
1164 /**
1165  * gst_rtp_buffer_get_payload_subbuffer:
1166  * @buffer: the buffer
1167  * @offset: the offset in the payload
1168  * @len: the length in the payload
1169  *
1170  * Create a subbuffer of the payload of the RTP packet in @buffer. @offset bytes
1171  * are skipped in the payload and the subbuffer will be of size @len.
1172  * If @len is -1 the total payload starting from @offset if subbuffered.
1173  *
1174  * Returns: A new buffer with the specified data of the payload.
1175  *
1176  * Since: 0.10.10
1177  */
1178 GstBuffer *
1179 gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset,
1180     guint len)
1181 {
1182   guint poffset, plen;
1183
1184   plen = gst_rtp_buffer_get_payload_len (buffer);
1185   /* we can't go past the length */
1186   if (G_UNLIKELY (offset >= plen))
1187     goto wrong_offset;
1188
1189   /* apply offset */
1190   poffset = gst_rtp_buffer_get_header_len (buffer) + offset;
1191   plen -= offset;
1192
1193   /* see if we need to shrink the buffer based on @len */
1194   if (len != -1 && len < plen)
1195     plen = len;
1196
1197   return gst_buffer_create_sub (buffer, poffset, plen);
1198
1199   /* ERRORS */
1200 wrong_offset:
1201   {
1202     g_warning ("offset=%u should be less then plen=%u", offset, plen);
1203     return NULL;
1204   }
1205 }
1206
1207 /**
1208  * gst_rtp_buffer_get_payload_buffer:
1209  * @buffer: the buffer
1210  *
1211  * Create a buffer of the payload of the RTP packet in @buffer. This function
1212  * will internally create a subbuffer of @buffer so that a memcpy can be
1213  * avoided.
1214  *
1215  * Returns: A new buffer with the data of the payload.
1216  */
1217 GstBuffer *
1218 gst_rtp_buffer_get_payload_buffer (GstBuffer * buffer)
1219 {
1220   return gst_rtp_buffer_get_payload_subbuffer (buffer, 0, -1);
1221 }
1222
1223 /**
1224  * gst_rtp_buffer_get_payload_len:
1225  * @buffer: the buffer
1226  *
1227  * Get the length of the payload of the RTP packet in @buffer.
1228  *
1229  * Returns: The length of the payload in @buffer.
1230  */
1231 guint
1232 gst_rtp_buffer_get_payload_len (GstBuffer * buffer)
1233 {
1234   guint len, size;
1235   guint8 *data;
1236
1237   size = GST_BUFFER_SIZE (buffer);
1238   data = GST_BUFFER_DATA (buffer);
1239
1240   len = size - gst_rtp_buffer_get_header_len (buffer);
1241
1242   if (GST_RTP_HEADER_PADDING (data))
1243     len -= data[size - 1];
1244
1245   return len;
1246 }
1247
1248 /**
1249  * gst_rtp_buffer_list_get_payload_len:
1250  * @list: the buffer list
1251  *
1252  * Get the length of the payload of the RTP packet in @list.
1253  *
1254  * Returns: The length of the payload in @list.
1255  *
1256  * Since: 0.10.24
1257  */
1258 guint
1259 gst_rtp_buffer_list_get_payload_len (GstBufferList * list)
1260 {
1261   guint len;
1262   GstBufferListIterator *it;
1263
1264   it = gst_buffer_list_iterate (list);
1265   len = 0;
1266
1267   while (gst_buffer_list_iterator_next_group (it)) {
1268     guint i;
1269     GstBuffer *buf;
1270
1271     i = 0;
1272     while ((buf = gst_buffer_list_iterator_next (it))) {
1273       /* skip the RTP header */
1274       if (!i++)
1275         continue;
1276       /* take the size of the current buffer */
1277       len += GST_BUFFER_SIZE (buf);
1278     }
1279   }
1280
1281   gst_buffer_list_iterator_free (it);
1282
1283   return len;
1284 }
1285
1286 /**
1287  * gst_rtp_buffer_get_payload:
1288  * @buffer: the buffer
1289  *
1290  * Get a pointer to the payload data in @buffer. This pointer is valid as long
1291  * as a reference to @buffer is held.
1292  *
1293  * Returns: A pointer to the payload data in @buffer.
1294  */
1295 gpointer
1296 gst_rtp_buffer_get_payload (GstBuffer * buffer)
1297 {
1298   return GST_BUFFER_DATA (buffer) + gst_rtp_buffer_get_header_len (buffer);
1299 }
1300
1301 /**
1302  * gst_rtp_buffer_default_clock_rate:
1303  * @payload_type: the static payload type
1304  *
1305  * Get the default clock-rate for the static payload type @payload_type.
1306  *
1307  * Returns: the default clock rate or -1 if the payload type is not static or
1308  * the clock-rate is undefined.
1309  *
1310  * Since: 0.10.13
1311  */
1312 guint32
1313 gst_rtp_buffer_default_clock_rate (guint8 payload_type)
1314 {
1315   const GstRTPPayloadInfo *info;
1316   guint32 res;
1317
1318   info = gst_rtp_payload_info_for_pt (payload_type);
1319   if (!info)
1320     return -1;
1321
1322   res = info->clock_rate;
1323   /* 0 means unknown so we have to return -1 from this function */
1324   if (res == 0)
1325     res = -1;
1326
1327   return res;
1328 }
1329
1330 /**
1331  * gst_rtp_buffer_compare_seqnum:
1332  * @seqnum1: a sequence number
1333  * @seqnum2: a sequence number
1334  *
1335  * Compare two sequence numbers, taking care of wraparounds. This function
1336  * returns the difference between @seqnum1 and @seqnum2.
1337  *
1338  * Returns: a negative value if @seqnum1 is bigger than @seqnum2, 0 if they
1339  * are equal or a positive value if @seqnum1 is smaller than @segnum2.
1340  *
1341  * Since: 0.10.15
1342  */
1343 gint
1344 gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2)
1345 {
1346   return (gint16) (seqnum2 - seqnum1);
1347 }
1348
1349 /**
1350  * gst_rtp_buffer_ext_timestamp:
1351  * @exttimestamp: a previous extended timestamp
1352  * @timestamp: a new timestamp
1353  *
1354  * Update the @exttimestamp field with @timestamp. For the first call of the
1355  * method, @exttimestamp should point to a location with a value of -1.
1356  *
1357  * This function makes sure that the returned value is a constantly increasing
1358  * value even in the case where there is a timestamp wraparound.
1359  *
1360  * Returns: The extended timestamp of @timestamp.
1361  *
1362  * Since: 0.10.15
1363  */
1364 guint64
1365 gst_rtp_buffer_ext_timestamp (guint64 * exttimestamp, guint32 timestamp)
1366 {
1367   guint64 result, diff, ext;
1368
1369   g_return_val_if_fail (exttimestamp != NULL, -1);
1370
1371   ext = *exttimestamp;
1372
1373   if (ext == -1) {
1374     result = timestamp;
1375   } else {
1376     /* pick wraparound counter from previous timestamp and add to new timestamp */
1377     result = timestamp + (ext & ~(G_GINT64_CONSTANT (0xffffffff)));
1378
1379     /* check for timestamp wraparound */
1380     if (result < ext)
1381       diff = ext - result;
1382     else
1383       diff = result - ext;
1384
1385     if (diff > G_MAXINT32) {
1386       /* timestamp went backwards more than allowed, we wrap around and get
1387        * updated extended timestamp. */
1388       result += (G_GINT64_CONSTANT (1) << 32);
1389     }
1390   }
1391   *exttimestamp = result;
1392
1393   return result;
1394 }
1395
1396 /**
1397  * gst_rtp_buffer_get_extension_onebyte_header:
1398  * @buffer: the buffer
1399  * @id: The ID of the header extension to be read (between 1 and 14).
1400  * @nth: Read the nth extension packet with the requested ID
1401  * @data: location for data
1402  * @size: the size of the data in bytes
1403  *
1404  * Parses RFC 5285 style header extensions with a one byte header. It will
1405  * return the nth extension with the requested id.
1406  *
1407  * Returns: TRUE if @buffer had the requested header extension
1408  *
1409  * Since: 0.10.31
1410  */
1411
1412 gboolean
1413 gst_rtp_buffer_get_extension_onebyte_header (GstBuffer * buffer, guint8 id,
1414     guint nth, gpointer * data, guint * size)
1415 {
1416   guint16 bits;
1417   guint8 *pdata;
1418   guint wordlen;
1419   gulong offset = 0;
1420   guint count = 0;
1421
1422   g_return_val_if_fail (id > 0 && id < 15, FALSE);
1423
1424   if (!gst_rtp_buffer_get_extension_data (buffer, &bits, (gpointer) & pdata,
1425           &wordlen))
1426     return FALSE;
1427
1428   if (bits != 0xBEDE)
1429     return FALSE;
1430
1431   for (;;) {
1432     guint8 read_id, read_len;
1433
1434     if (offset + 1 >= wordlen * 4)
1435       break;
1436
1437     read_id = GST_READ_UINT8 (pdata + offset) >> 4;
1438     read_len = (GST_READ_UINT8 (pdata + offset) & 0x0F) + 1;
1439     offset += 1;
1440
1441     /* ID 0 means its padding, skip */
1442     if (read_id == 0)
1443       continue;
1444
1445     /* ID 15 is special and means we should stop parsing */
1446     if (read_id == 15)
1447       break;
1448
1449     /* Ignore extension headers where the size does not fit */
1450     if (offset + read_len > wordlen * 4)
1451       break;
1452
1453     /* If we have the right one */
1454     if (id == read_id) {
1455       if (nth == count) {
1456         if (data)
1457           *data = pdata + offset;
1458         if (size)
1459           *size = read_len;
1460
1461         return TRUE;
1462       }
1463
1464       count++;
1465     }
1466     offset += read_len;
1467
1468     if (offset >= wordlen * 4)
1469       break;
1470   }
1471
1472   return FALSE;
1473 }
1474
1475 /**
1476  * gst_rtp_buffer_get_extension_twobytes_header:
1477  * @buffer: the buffer
1478  * @appbits: Application specific bits
1479  * @id: The ID of the header extension to be read (between 1 and 14).
1480  * @nth: Read the nth extension packet with the requested ID
1481  * @data: location for data
1482  * @size: the size of the data in bytes
1483  *
1484  * Parses RFC 5285 style header extensions with a two bytes header. It will
1485  * return the nth extension with the requested id.
1486  *
1487  * Returns: TRUE if @buffer had the requested header extension
1488  *
1489  * Since: 0.10.31
1490  */
1491
1492 gboolean
1493 gst_rtp_buffer_get_extension_twobytes_header (GstBuffer * buffer,
1494     guint8 * appbits, guint8 id, guint nth, gpointer * data, guint * size)
1495 {
1496   guint16 bits;
1497   guint8 *pdata;
1498   guint wordlen;
1499   guint bytelen;
1500   gulong offset = 0;
1501   guint count = 0;
1502
1503   if (!gst_rtp_buffer_get_extension_data (buffer, &bits, (gpointer) & pdata,
1504           &wordlen))
1505     return FALSE;
1506
1507   if (bits >> 4 != 0x100)
1508     return FALSE;
1509
1510   bytelen = wordlen * 4;
1511
1512   for (;;) {
1513     guint8 read_id, read_len;
1514
1515     if (offset + 2 >= bytelen)
1516       break;
1517
1518     read_id = GST_READ_UINT8 (pdata + offset);
1519     offset += 1;
1520
1521     if (read_id == 0)
1522       continue;
1523
1524     read_len = GST_READ_UINT8 (pdata + offset);
1525     offset += 1;
1526
1527     /* Ignore extension headers where the size does not fit */
1528     if (offset + read_len > bytelen)
1529       break;
1530
1531     /* If we have the right one, return it */
1532     if (id == read_id) {
1533       if (nth == count) {
1534         if (data)
1535           *data = pdata + offset;
1536         if (size)
1537           *size = read_len;
1538         if (appbits)
1539           *appbits = bits;
1540
1541         return TRUE;
1542       }
1543
1544       count++;
1545     }
1546     offset += read_len;
1547   }
1548
1549   return FALSE;
1550 }
1551
1552 static guint
1553 get_onebyte_header_end_offset (guint8 * pdata, guint wordlen)
1554 {
1555   guint offset = 0;
1556   guint bytelen = wordlen * 4;
1557   guint paddingcount = 0;
1558
1559   while (offset + 1 < bytelen) {
1560     guint8 read_id, read_len;
1561
1562     read_id = GST_READ_UINT8 (pdata + offset) >> 4;
1563     read_len = (GST_READ_UINT8 (pdata + offset) & 0x0F) + 1;
1564     offset += 1;
1565
1566     /* ID 0 means its padding, skip */
1567     if (read_id == 0) {
1568       paddingcount++;
1569       continue;
1570     }
1571
1572     paddingcount = 0;
1573
1574     /* ID 15 is special and means we should stop parsing */
1575     /* It also means we can't add an extra packet */
1576     if (read_id == 15)
1577       return 0;
1578
1579     /* Ignore extension headers where the size does not fit */
1580     if (offset + read_len > bytelen)
1581       return 0;
1582
1583     offset += read_len;
1584   }
1585
1586   return offset - paddingcount;
1587 }
1588
1589 /**
1590  * gst_rtp_buffer_add_extension_onebyte_header:
1591  * @buffer: the buffer
1592  * @id: The ID of the header extension (between 1 and 14).
1593  * @data: location for data
1594  * @size: the size of the data in bytes
1595  *
1596  * Adds a RFC 5285 header extension with a one byte header to the end of the
1597  * RTP header. If there is already a RFC 5285 header extension with a one byte
1598  * header, the new extension will be appended.
1599  * It will not work if there is already a header extension that does not follow
1600  * the mecanism described in RFC 5285 or if there is a header extension with
1601  * a two bytes header as described in RFC 5285. In that case, use
1602  * gst_rtp_buffer_add_extension_twobytes_header()
1603  *
1604  * Returns: %TRUE if header extension could be added
1605  *
1606  * Since: 0.10.31
1607  */
1608
1609 gboolean
1610 gst_rtp_buffer_add_extension_onebyte_header (GstBuffer * buffer, guint8 id,
1611     gpointer data, guint size)
1612 {
1613   guint16 bits;
1614   guint8 *pdata;
1615   guint wordlen;
1616   gboolean has_bit;
1617
1618   g_return_val_if_fail (id > 0 && id < 15, FALSE);
1619   g_return_val_if_fail (size >= 1 && size <= 16, FALSE);
1620   g_return_val_if_fail (gst_buffer_is_writable (buffer), FALSE);
1621
1622   has_bit = gst_rtp_buffer_get_extension_data (buffer, &bits,
1623       (gpointer) & pdata, &wordlen);
1624
1625   if (has_bit) {
1626     gulong offset = 0;
1627     guint8 *nextext;
1628     guint extlen;
1629
1630     if (bits != 0xBEDE)
1631       return FALSE;
1632
1633     offset = get_onebyte_header_end_offset (pdata, wordlen);
1634     if (offset == 0)
1635       return FALSE;
1636
1637     nextext = pdata + offset;
1638     offset = nextext - GST_BUFFER_DATA (buffer);
1639
1640     /* Don't add extra header if there isn't enough space */
1641     if (GST_BUFFER_SIZE (buffer) < offset + size + 1)
1642       return FALSE;
1643
1644     nextext[0] = (id << 4) | (0x0F & (size - 1));
1645     memcpy (nextext + 1, data, size);
1646
1647     extlen = nextext - pdata + size + 1;
1648     if (extlen % 4) {
1649       wordlen = extlen / 4 + 1;
1650       memset (nextext + size + 1, 0, 4 - extlen % 4);
1651     } else {
1652       wordlen = extlen / 4;
1653     }
1654
1655     gst_rtp_buffer_set_extension_data (buffer, 0xBEDE, wordlen);
1656   } else {
1657     wordlen = (size + 1) / 4 + (((size + 1) % 4) ? 1 : 0);
1658
1659     gst_rtp_buffer_set_extension_data (buffer, 0xBEDE, wordlen);
1660
1661     gst_rtp_buffer_get_extension_data (buffer, &bits,
1662         (gpointer) & pdata, &wordlen);
1663
1664     pdata[0] = (id << 4) | (0x0F & (size - 1));
1665     memcpy (pdata + 1, data, size);
1666
1667     if ((size + 1) % 4)
1668       memset (pdata + size + 1, 0, 4 - ((size + 1) % 4));
1669   }
1670
1671   return TRUE;
1672 }
1673
1674
1675 static guint
1676 get_twobytes_header_end_offset (guint8 * pdata, guint wordlen)
1677 {
1678   guint offset = 0;
1679   guint bytelen = wordlen * 4;
1680   guint paddingcount = 0;
1681
1682   while (offset + 2 < bytelen) {
1683     guint8 read_id, read_len;
1684
1685     read_id = GST_READ_UINT8 (pdata + offset);
1686     offset += 1;
1687
1688     /* ID 0 means its padding, skip */
1689     if (read_id == 0) {
1690       paddingcount++;
1691       continue;
1692     }
1693
1694     paddingcount = 0;
1695
1696     read_len = GST_READ_UINT8 (pdata + offset);
1697     offset += 1;
1698
1699     /* Ignore extension headers where the size does not fit */
1700     if (offset + read_len > bytelen)
1701       return 0;
1702
1703     offset += read_len;
1704   }
1705
1706   return offset - paddingcount;
1707 }
1708
1709 /**
1710  * gst_rtp_buffer_add_extension_twobytes_header:
1711  * @buffer: the buffer
1712  * @appbits: Application specific bits
1713  * @id: The ID of the header extension
1714  * @data: location for data
1715  * @size: the size of the data in bytes
1716  *
1717  * Adds a RFC 5285 header extension with a two bytes header to the end of the
1718  * RTP header. If there is already a RFC 5285 header extension with a two bytes
1719  * header, the new extension will be appended.
1720  * It will not work if there is already a header extension that does not follow
1721  * the mecanism described in RFC 5285 or if there is a header extension with
1722  * a one byte header as described in RFC 5285. In that case, use
1723  * gst_rtp_buffer_add_extension_onebyte_header()
1724  *
1725  * Returns: %TRUE if header extension could be added
1726  *
1727  * Since: 0.10.31
1728  */
1729
1730 gboolean
1731 gst_rtp_buffer_add_extension_twobytes_header (GstBuffer * buffer,
1732     guint8 appbits, guint8 id, gpointer data, guint size)
1733 {
1734   guint16 bits;
1735   guint8 *pdata;
1736   guint wordlen;
1737   gboolean has_bit;
1738
1739   g_return_val_if_fail ((appbits & 0xF0) == 0, FALSE);
1740   g_return_val_if_fail (size < 256, FALSE);
1741   g_return_val_if_fail (gst_buffer_is_writable (buffer), FALSE);
1742
1743   has_bit = gst_rtp_buffer_get_extension_data (buffer, &bits,
1744       (gpointer) & pdata, &wordlen);
1745
1746   if (has_bit) {
1747     gulong offset = 0;
1748     guint8 *nextext;
1749     guint extlen;
1750
1751     if (bits != ((0x100 << 4) | (appbits & 0x0f)))
1752       return FALSE;
1753
1754     offset = get_twobytes_header_end_offset (pdata, wordlen);
1755
1756     nextext = pdata + offset;
1757
1758     offset = nextext - GST_BUFFER_DATA (buffer);
1759
1760     /* Don't add extra header if there isn't enough space */
1761     if (GST_BUFFER_SIZE (buffer) < offset + size + 2)
1762       return FALSE;
1763
1764     nextext[0] = id;
1765     nextext[1] = size;
1766     memcpy (nextext + 2, data, size);
1767
1768     extlen = nextext - pdata + size + 2;
1769     if (extlen % 4) {
1770       wordlen = extlen / 4 + 1;
1771       memset (nextext + size + 2, 0, 4 - extlen % 4);
1772     } else {
1773       wordlen = extlen / 4;
1774     }
1775
1776     gst_rtp_buffer_set_extension_data (buffer, (0x100 << 4) | (appbits & 0x0F),
1777         wordlen);
1778   } else {
1779     wordlen = (size + 2) / 4 + (((size + 2) % 4) ? 1 : 0);
1780
1781     gst_rtp_buffer_set_extension_data (buffer, (0x100 << 4) | (appbits & 0x0F),
1782         wordlen);
1783
1784     gst_rtp_buffer_get_extension_data (buffer, &bits,
1785         (gpointer) & pdata, &wordlen);
1786
1787     pdata[0] = id;
1788     pdata[1] = size;
1789     memcpy (pdata + 2, data, size);
1790     if ((size + 2) % 4)
1791       memset (pdata + size + 2, 0, 4 - ((size + 2) % 4));
1792   }
1793
1794   return TRUE;
1795 }
1796
1797 /**
1798  * gst_rtp_buffer_list_get_extension_onebyte_header:
1799  * @bufferlist: the bufferlist
1800  * @group_idx: The index of the group in the #GstBufferList
1801  * @id: The ID of the header extension to be read (between 1 and 14).
1802  * @nth: Read the nth extension packet with the requested ID
1803  * @data: location for data
1804  * @size: the size of the data in bytes
1805  *
1806  * Parses RFC 5285 style header extensions with a one byte header. It will
1807  * return the nth extension with the requested id.
1808  *
1809  * Returns: TRUE if @buffer had the requested header extension
1810  *
1811  * Since: 0.10.31
1812  */
1813
1814 gboolean
1815 gst_rtp_buffer_list_get_extension_onebyte_header (GstBufferList * bufferlist,
1816     guint group_idx, guint8 id, guint nth, gpointer * data, guint * size)
1817 {
1818   GstBuffer *buffer;
1819
1820   buffer = gst_buffer_list_get (bufferlist, group_idx, 0);
1821
1822   if (!buffer)
1823     return FALSE;
1824
1825   return gst_rtp_buffer_get_extension_onebyte_header (buffer, id, nth, data,
1826       size);
1827 }
1828
1829
1830 /**
1831  * gst_rtp_buffer_list_get_extension_twobytes_header:
1832  * @bufferlist: the bufferlist
1833  * @group_idx: The index of the group in the #GstBufferList
1834  * @appbits: Application specific bits
1835  * @id: The ID of the header extension to be read (between 1 and 14).
1836  * @nth: Read the nth extension packet with the requested ID
1837  * @data: location for data
1838  * @size: the size of the data in bytes
1839  *
1840  * Parses RFC 5285 style header extensions with a two bytes header. It will
1841  * return the nth extension with the requested id.
1842  *
1843  * Returns: TRUE if @buffer had the requested header extension
1844  *
1845  * Since: 0.10.31
1846  */
1847
1848 gboolean
1849 gst_rtp_buffer_list_get_extension_twobytes_header (GstBufferList * bufferlist,
1850     guint group_idx, guint8 * appbits, guint8 id, guint nth,
1851     gpointer * data, guint * size)
1852 {
1853   GstBuffer *buffer;
1854
1855   buffer = gst_buffer_list_get (bufferlist, group_idx, 0);
1856
1857   if (!buffer)
1858     return FALSE;
1859
1860   return gst_rtp_buffer_get_extension_twobytes_header (buffer, appbits, id,
1861       nth, data, size);
1862 }
1863
1864 /**
1865  * gst_rtp_buffer_list_add_extension_onebyte_header:
1866  * @it: a #GstBufferListIterator pointing right after the #GstBuffer where
1867  * the header extension should be added
1868  * @id: The ID of the header extension (between 1 and 14).
1869  * @data: location for data
1870  * @size: the size of the data in bytes
1871  *
1872  * Adds a RFC 5285 header extension with a one byte header to the end of the
1873  * RTP header. If there is already a RFC 5285 header extension with a one byte
1874  * header, the new extension will be appended.
1875  * It will not work if there is already a header extension that does not follow
1876  * the mecanism described in RFC 5285 or if there is a header extension with
1877  * a two bytes header as described in RFC 5285. In that case, use
1878  * gst_rtp_buffer_list_add_extension_twobytes_header()
1879  *
1880  * This function will not modify the data section of the RTP buffer, only
1881  * the header.
1882  *
1883  * Returns: %TRUE if header extension could be added
1884  *
1885  * Since: 0.10.31
1886  */
1887
1888 gboolean
1889 gst_rtp_buffer_list_add_extension_onebyte_header (GstBufferListIterator * it,
1890     guint8 id, gpointer data, guint size)
1891 {
1892   GstBuffer *buffer;
1893   guint16 bits;
1894   guint8 *pdata;
1895   guint wordlen;
1896   gboolean retval;
1897   guint endoffset = 0;
1898
1899   g_return_val_if_fail (gst_buffer_list_iterator_n_buffers (it) == 1, FALSE);
1900   g_return_val_if_fail (id > 0 && id < 15, FALSE);
1901   g_return_val_if_fail (size >= 1 && size <= 16, FALSE);
1902
1903   buffer = gst_buffer_list_iterator_steal (it);
1904
1905   if (GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer))) {
1906     gst_rtp_buffer_get_extension_data (buffer, &bits, (gpointer) & pdata,
1907         &wordlen);
1908
1909     if (bits != 0xBEDE)
1910       return FALSE;
1911
1912     endoffset = get_onebyte_header_end_offset (pdata, wordlen);
1913     if (endoffset == 0)
1914       return FALSE;
1915     endoffset += pdata - GST_BUFFER_DATA (buffer);
1916   } else {
1917     endoffset = GST_BUFFER_SIZE (buffer) + 4;
1918   }
1919
1920   if (endoffset + size + 1 > GST_BUFFER_SIZE (buffer)) {
1921     guint newsize;
1922     GstBuffer *newbuffer;
1923
1924     newsize = endoffset + size + 1;
1925     if (newsize % 4)
1926       newsize += 4 - (newsize % 4);
1927     newbuffer = gst_buffer_new_and_alloc (newsize);
1928     memcpy (GST_BUFFER_DATA (newbuffer), GST_BUFFER_DATA (buffer),
1929         GST_BUFFER_SIZE (buffer));
1930     gst_buffer_copy_metadata (newbuffer, buffer, GST_BUFFER_COPY_ALL);
1931     gst_buffer_unref (buffer);
1932     buffer = newbuffer;
1933   } else {
1934     buffer = gst_buffer_make_writable (buffer);
1935   }
1936
1937   retval = gst_rtp_buffer_add_extension_onebyte_header (buffer, id, data, size);
1938
1939   gst_buffer_list_iterator_take (it, buffer);
1940
1941   return retval;
1942 }
1943
1944 /**
1945  * gst_rtp_buffer_list_add_extension_twobytes_header:
1946  * @it: a #GstBufferListIterator pointing right after the #GstBuffer where
1947  * the header extension should be added
1948  * @appbits: Application specific bits
1949  * @id: The ID of the header extension
1950  * @data: location for data
1951  * @size: the size of the data in bytes
1952  *
1953  * Adds a RFC 5285 header extension with a two bytes header to the end of the
1954  * RTP header. If there is already a RFC 5285 header extension with a two bytes
1955  * header, the new extension will be appended.
1956  * It will not work if there is already a header extension that does not follow
1957  * the mecanism described in RFC 5285 or if there is a header extension with
1958  * a one byte header as described in RFC 5285. In that case, use
1959  * gst_rtp_buffer_add_extension_onebyte_header()
1960  *
1961  * This function will not modify the data section of the RTP buffer, only
1962  * the header.
1963  *
1964  * Returns: %TRUE if header extension could be added
1965  *
1966  * Since: 0.10.31
1967  */
1968
1969 gboolean
1970 gst_rtp_buffer_list_add_extension_twobytes_header (GstBufferListIterator * it,
1971     guint8 appbits, guint8 id, gpointer data, guint size)
1972 {
1973   GstBuffer *buffer;
1974   guint16 bits;
1975   guint8 *pdata;
1976   guint wordlen;
1977   gboolean retval;
1978   guint endoffset;
1979
1980   g_return_val_if_fail ((appbits & 0xF0) == 0, FALSE);
1981   g_return_val_if_fail (size < 256, FALSE);
1982   g_return_val_if_fail (gst_buffer_list_iterator_n_buffers (it) == 1, FALSE);
1983
1984   buffer = gst_buffer_list_iterator_steal (it);
1985
1986   if (GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer))) {
1987     gst_rtp_buffer_get_extension_data (buffer, &bits, (gpointer) & pdata,
1988         &wordlen);
1989
1990     if (bits != ((0x100 << 4) | (appbits & 0x0f)))
1991       return FALSE;
1992
1993     endoffset = get_twobytes_header_end_offset (pdata, wordlen);
1994     if (endoffset == 0)
1995       return FALSE;
1996     endoffset += pdata - GST_BUFFER_DATA (buffer);
1997   } else {
1998     endoffset = GST_BUFFER_SIZE (buffer) + 4;
1999   }
2000
2001   if (endoffset + size + 2 > GST_BUFFER_SIZE (buffer)) {
2002     guint newsize;
2003     GstBuffer *newbuffer;
2004
2005     newsize = endoffset + size + 2;
2006     if (newsize % 4)
2007       newsize += 4 - newsize % 4;
2008     newbuffer = gst_buffer_new_and_alloc (newsize);
2009     memcpy (GST_BUFFER_DATA (newbuffer), GST_BUFFER_DATA (buffer),
2010         GST_BUFFER_SIZE (buffer));
2011     gst_buffer_copy_metadata (newbuffer, buffer, GST_BUFFER_COPY_ALL);
2012     gst_buffer_unref (buffer);
2013     buffer = newbuffer;
2014   } else {
2015     buffer = gst_buffer_make_writable (buffer);
2016   }
2017
2018   retval = gst_rtp_buffer_add_extension_twobytes_header (buffer, appbits, id,
2019       data, size);
2020
2021   gst_buffer_list_iterator_take (it, buffer);
2022
2023   return retval;
2024 }
2025
2026 /**
2027  * gst_rtp_buffer_list_from_buffer:
2028  * @buffer: a #GstBuffer containing a RTP packet
2029  *
2030  * Splits a #GstBuffer into a #GstBufferList containing separate
2031  * buffers for the header and data sections.
2032  *
2033  * Returns: a #GstBufferList
2034  */
2035
2036 GstBufferList *
2037 gst_rtp_buffer_list_from_buffer (GstBuffer * buffer)
2038 {
2039   GstBufferList *bufferlist;
2040   GstBuffer *sub;
2041   GstBufferListIterator *it;
2042   guint8 *payload;
2043
2044   bufferlist = gst_buffer_list_new ();
2045
2046   it = gst_buffer_list_iterate (bufferlist);
2047   gst_buffer_list_iterator_add_group (it);
2048
2049   payload = gst_rtp_buffer_get_payload (buffer);
2050   sub = gst_buffer_create_sub (buffer, 0, payload - GST_BUFFER_DATA (buffer));
2051   gst_buffer_list_iterator_add (it, sub);
2052
2053   sub = gst_rtp_buffer_get_payload_buffer (buffer);
2054   gst_buffer_list_iterator_add (it, sub);
2055
2056   gst_buffer_list_iterator_free (it);
2057
2058   return bufferlist;
2059 }