update for new memory api
[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: #GstRTPBasePayload, #GstRTPBaseDepayload, 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   GstMapInfo map;
103   GstMemory *mem;
104   gsize len;
105
106   g_return_if_fail (csrc_count <= 15);
107   g_return_if_fail (GST_IS_BUFFER (buffer));
108
109   len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
110       + payload_len + pad_len;
111
112   mem = gst_allocator_alloc (NULL, len, 0);
113
114   gst_memory_map (mem, &map, GST_MAP_WRITE);
115   /* fill in defaults */
116   GST_RTP_HEADER_VERSION (map.data) = GST_RTP_VERSION;
117   GST_RTP_HEADER_PADDING (map.data) = FALSE;
118   GST_RTP_HEADER_EXTENSION (map.data) = FALSE;
119   GST_RTP_HEADER_CSRC_COUNT (map.data) = csrc_count;
120   memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (map.data, 0), 0,
121       csrc_count * sizeof (guint32));
122   GST_RTP_HEADER_MARKER (map.data) = FALSE;
123   GST_RTP_HEADER_PAYLOAD_TYPE (map.data) = 0;
124   GST_RTP_HEADER_SEQ (map.data) = 0;
125   GST_RTP_HEADER_TIMESTAMP (map.data) = 0;
126   GST_RTP_HEADER_SSRC (map.data) = 0;
127   gst_memory_unmap (mem, &map);
128
129   gst_buffer_take_memory (buffer, -1, mem);
130 }
131
132 /**
133  * gst_rtp_buffer_new_take_data:
134  * @data: data for the new buffer
135  * @len: the length of data
136  *
137  * Create a new buffer and set the data and size of the buffer to @data and @len
138  * respectively. @data will be freed when the buffer is unreffed, so this
139  * function transfers ownership of @data to the new buffer.
140  *
141  * Returns: A newly allocated buffer with @data and of size @len.
142  */
143 GstBuffer *
144 gst_rtp_buffer_new_take_data (gpointer data, gsize len)
145 {
146   GstBuffer *result;
147
148   g_return_val_if_fail (data != NULL, NULL);
149   g_return_val_if_fail (len > 0, NULL);
150
151   result = gst_buffer_new ();
152   gst_buffer_take_memory (result, -1,
153       gst_memory_new_wrapped (0, data, len, 0, len, data, g_free));
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, gsize 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 extension 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, gsize 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  * gst_rtp_buffer_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   gboolean res;
414   GstMapInfo map;
415
416   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
417
418   gst_buffer_map (buffer, &map, GST_MAP_READ);
419   res = validate_data (map.data, map.size, NULL, 0);
420   gst_buffer_unmap (buffer, &map);
421
422   return res;
423 }
424
425 gboolean
426 gst_rtp_buffer_map (GstBuffer * buffer, GstMapFlags flags, GstRTPBuffer * rtp)
427 {
428   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
429   g_return_val_if_fail (rtp != NULL, FALSE);
430   g_return_val_if_fail (rtp->buffer == NULL, FALSE);
431
432   if (!gst_buffer_map (buffer, &rtp->map, flags))
433     return FALSE;
434
435   rtp->buffer = buffer;
436
437   return TRUE;
438 }
439
440 gboolean
441 gst_rtp_buffer_unmap (GstRTPBuffer * rtp)
442 {
443   g_return_val_if_fail (rtp != NULL, FALSE);
444   g_return_val_if_fail (rtp->buffer != NULL, FALSE);
445
446   gst_buffer_unmap (rtp->buffer, &rtp->map);
447   rtp->buffer = NULL;
448
449   return TRUE;
450 }
451
452
453 /**
454  * gst_rtp_buffer_set_packet_len:
455  * @rtp: the RTP packet
456  * @len: the new packet length
457  *
458  * Set the total @rtp size to @len. The data in the buffer will be made
459  * larger if needed. Any padding will be removed from the packet.
460  */
461 void
462 gst_rtp_buffer_set_packet_len (GstRTPBuffer * rtp, guint len)
463 {
464   guint8 *data;
465
466   data = rtp->map.data;
467
468   if (rtp->map.maxsize <= len) {
469     /* FIXME, realloc bigger space */
470     g_warning ("not implemented");
471   }
472
473   gst_buffer_set_size (rtp->buffer, len);
474   rtp->map.size = len;
475
476   /* remove any padding */
477   GST_RTP_HEADER_PADDING (data) = FALSE;
478 }
479
480 /**
481  * gst_rtp_buffer_get_packet_len:
482  * @rtp: the RTP packet
483  *
484  * Return the total length of the packet in @buffer.
485  *
486  * Returns: The total length of the packet in @buffer.
487  */
488 guint
489 gst_rtp_buffer_get_packet_len (GstRTPBuffer * rtp)
490 {
491   return gst_buffer_get_size (rtp->buffer);
492 }
493
494 /**
495  * gst_rtp_buffer_get_header_len:
496  * @rtp: the RTP packet
497  *
498  * Return the total length of the header in @buffer. This include the length of
499  * the fixed header, the CSRC list and the extension header.
500  *
501  * Returns: The total length of the header in @buffer.
502  */
503 guint
504 gst_rtp_buffer_get_header_len (GstRTPBuffer * rtp)
505 {
506   guint len;
507   guint8 *data;
508
509   data = rtp->map.data;
510
511   len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
512   if (GST_RTP_HEADER_EXTENSION (data))
513     len += GST_READ_UINT16_BE (data + len + 2) * 4 + 4;
514
515   return len;
516 }
517
518 /**
519  * gst_rtp_buffer_get_version:
520  * @rtp: the RTP packet
521  *
522  * Get the version number of the RTP packet in @buffer.
523  *
524  * Returns: The version of @buffer.
525  */
526 guint8
527 gst_rtp_buffer_get_version (GstRTPBuffer * rtp)
528 {
529   return GST_RTP_HEADER_VERSION (rtp->map.data);
530 }
531
532 /**
533  * gst_rtp_buffer_set_version:
534  * @rtp: the RTP packet
535  * @version: the new version
536  *
537  * Set the version of the RTP packet in @buffer to @version.
538  */
539 void
540 gst_rtp_buffer_set_version (GstRTPBuffer * rtp, guint8 version)
541 {
542   g_return_if_fail (version < 0x04);
543
544   GST_RTP_HEADER_VERSION (rtp->map.data) = version;
545 }
546
547 /**
548  * gst_rtp_buffer_get_padding:
549  * @rtp: the RTP packet
550  *
551  * Check if the padding bit is set on the RTP packet in @buffer.
552  *
553  * Returns: TRUE if @buffer has the padding bit set.
554  */
555 gboolean
556 gst_rtp_buffer_get_padding (GstRTPBuffer * rtp)
557 {
558   return GST_RTP_HEADER_PADDING (rtp->map.data);
559 }
560
561 /**
562  * gst_rtp_buffer_set_padding:
563  * @rtp: the buffer
564  * @padding: the new padding
565  *
566  * Set the padding bit on the RTP packet in @buffer to @padding.
567  */
568 void
569 gst_rtp_buffer_set_padding (GstRTPBuffer * rtp, gboolean padding)
570 {
571   GST_RTP_HEADER_PADDING (rtp->map.data) = padding;
572 }
573
574 /**
575  * gst_rtp_buffer_pad_to:
576  * @rtp: the RTP packet
577  * @len: the new amount of padding
578  *
579  * Set the amount of padding in the RTP packet in @buffer to
580  * @len. If @len is 0, the padding is removed.
581  *
582  * NOTE: This function does not work correctly.
583  */
584 void
585 gst_rtp_buffer_pad_to (GstRTPBuffer * rtp, guint len)
586 {
587   guint8 *data;
588
589   data = rtp->map.data;
590
591   if (len > 0)
592     GST_RTP_HEADER_PADDING (data) = TRUE;
593   else
594     GST_RTP_HEADER_PADDING (data) = FALSE;
595
596   /* FIXME, set the padding byte at the end of the payload data */
597 }
598
599 /**
600  * gst_rtp_buffer_get_extension:
601  * @rtp: the RTP packet
602  *
603  * Check if the extension bit is set on the RTP packet in @buffer.
604  * 
605  * Returns: TRUE if @buffer has the extension bit set.
606  */
607 gboolean
608 gst_rtp_buffer_get_extension (GstRTPBuffer * rtp)
609 {
610   return GST_RTP_HEADER_EXTENSION (rtp->map.data);
611 }
612
613 /**
614  * gst_rtp_buffer_set_extension:
615  * @rtp: the RTP packet
616  * @extension: the new extension
617  *
618  * Set the extension bit on the RTP packet in @buffer to @extension.
619  */
620 void
621 gst_rtp_buffer_set_extension (GstRTPBuffer * rtp, gboolean extension)
622 {
623   GST_RTP_HEADER_EXTENSION (rtp->map.data) = extension;
624 }
625
626 /**
627  * gst_rtp_buffer_get_extension_data:
628  * @rtp: the RTP packet
629  * @bits: location for result bits
630  * @data: location for data
631  * @wordlen: location for length of @data in 32 bits words
632  *
633  * Get the extension data. @bits will contain the extension 16 bits of custom
634  * data. @data will point to the data in the extension and @wordlen will contain
635  * the length of @data in 32 bits words.
636  *
637  * If @buffer did not contain an extension, this function will return %FALSE
638  * with @bits, @data and @wordlen unchanged.
639  * 
640  * Returns: TRUE if @buffer had the extension bit set.
641  *
642  * Since: 0.10.15
643  */
644 gboolean
645 gst_rtp_buffer_get_extension_data (GstRTPBuffer * rtp, guint16 * bits,
646     gpointer * data, guint * wordlen)
647 {
648   guint len;
649   guint8 *pdata;
650
651   pdata = rtp->map.data;
652
653   if (!GST_RTP_HEADER_EXTENSION (pdata))
654     return FALSE;
655
656   /* move to the extension */
657   len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (pdata);
658   pdata += len;
659
660   if (bits)
661     *bits = GST_READ_UINT16_BE (pdata);
662   if (wordlen)
663     *wordlen = GST_READ_UINT16_BE (pdata + 2);
664   pdata += 4;
665   if (data)
666     *data = (gpointer *) pdata;
667
668   return TRUE;
669 }
670
671 /**
672  * gst_rtp_buffer_set_extension_data:
673  * @rtp: the RTP packet
674  * @bits: the bits specific for the extension
675  * @length: the length that counts the number of 32-bit words in
676  * the extension, excluding the extension header ( therefore zero is a valid length)
677  *
678  * Set the extension bit of the rtp buffer and fill in the @bits and @length of the
679  * extension header. It will refuse to set the extension data if the buffer is not
680  * large enough.
681  *
682  * Returns: True if done.
683  *
684  * Since: 0.10.18
685  */
686 gboolean
687 gst_rtp_buffer_set_extension_data (GstRTPBuffer * rtp, guint16 bits,
688     guint16 length)
689 {
690   guint32 min_size = 0;
691   guint8 *data;
692
693   data = rtp->map.data;
694
695   /* check if the buffer is big enough to hold the extension */
696   min_size =
697       GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data) + 4 +
698       length * sizeof (guint32);
699   if (G_UNLIKELY (min_size > rtp->map.size))
700     goto too_small;
701
702   /* now we can set the extension bit */
703   GST_RTP_HEADER_EXTENSION (rtp->map.data) = TRUE;
704
705   data += GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
706   GST_WRITE_UINT16_BE (data, bits);
707   GST_WRITE_UINT16_BE (data + 2, length);
708
709   return TRUE;
710
711   /* ERRORS */
712 too_small:
713   {
714     g_warning
715         ("rtp buffer too small: need more than %d bytes but only have %"
716         G_GSIZE_FORMAT " bytes", min_size, rtp->map.size);
717     return FALSE;
718   }
719 }
720
721 /**
722  * gst_rtp_buffer_get_ssrc:
723  * @rtp: the RTP packet
724  *
725  * Get the SSRC of the RTP packet in @buffer.
726  * 
727  * Returns: the SSRC of @buffer in host order.
728  */
729 guint32
730 gst_rtp_buffer_get_ssrc (GstRTPBuffer * rtp)
731 {
732   return g_ntohl (GST_RTP_HEADER_SSRC (rtp->map.data));
733 }
734
735 /**
736  * gst_rtp_buffer_set_ssrc:
737  * @rtp: the RTP packet
738  * @ssrc: the new SSRC
739  *
740  * Set the SSRC on the RTP packet in @buffer to @ssrc.
741  */
742 void
743 gst_rtp_buffer_set_ssrc (GstRTPBuffer * rtp, guint32 ssrc)
744 {
745   GST_RTP_HEADER_SSRC (rtp->map.data) = g_htonl (ssrc);
746 }
747
748 /**
749  * gst_rtp_buffer_get_csrc_count:
750  * @rtp: the RTP packet
751  *
752  * Get the CSRC count of the RTP packet in @buffer.
753  * 
754  * Returns: the CSRC count of @buffer.
755  */
756 guint8
757 gst_rtp_buffer_get_csrc_count (GstRTPBuffer * rtp)
758 {
759   return GST_RTP_HEADER_CSRC_COUNT (rtp->map.data);
760 }
761
762 /**
763  * gst_rtp_buffer_get_csrc:
764  * @rtp: the RTP packet
765  * @idx: the index of the CSRC to get
766  *
767  * Get the CSRC at index @idx in @buffer.
768  * 
769  * Returns: the CSRC at index @idx in host order.
770  */
771 guint32
772 gst_rtp_buffer_get_csrc (GstRTPBuffer * rtp, guint8 idx)
773 {
774   guint8 *data;
775
776   data = rtp->map.data;
777
778   g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data), 0);
779
780   return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx));
781 }
782
783 /**
784  * gst_rtp_buffer_set_csrc:
785  * @rtp: the RTP packet
786  * @idx: the CSRC index to set
787  * @csrc: the CSRC in host order to set at @idx
788  *
789  * Modify the CSRC at index @idx in @buffer to @csrc.
790  */
791 void
792 gst_rtp_buffer_set_csrc (GstRTPBuffer * rtp, guint8 idx, guint32 csrc)
793 {
794   guint8 *data;
795
796   data = rtp->map.data;
797
798   g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data));
799
800   GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx), csrc);
801 }
802
803 /**
804  * gst_rtp_buffer_get_marker:
805  * @rtp: the RTP packet
806  *
807  * Check if the marker bit is set on the RTP packet in @buffer.
808  *
809  * Returns: TRUE if @buffer has the marker bit set.
810  */
811 gboolean
812 gst_rtp_buffer_get_marker (GstRTPBuffer * rtp)
813 {
814   return GST_RTP_HEADER_MARKER (rtp->map.data);
815 }
816
817 /**
818  * gst_rtp_buffer_set_marker:
819  * @rtp: the RTP packet
820  * @marker: the new marker
821  *
822  * Set the marker bit on the RTP packet in @buffer to @marker.
823  */
824 void
825 gst_rtp_buffer_set_marker (GstRTPBuffer * rtp, gboolean marker)
826 {
827   GST_RTP_HEADER_MARKER (rtp->map.data) = marker;
828 }
829
830 /**
831  * gst_rtp_buffer_get_payload_type:
832  * @rtp: the RTP packet
833  *
834  * Get the payload type of the RTP packet in @buffer.
835  *
836  * Returns: The payload type.
837  */
838 guint8
839 gst_rtp_buffer_get_payload_type (GstRTPBuffer * rtp)
840 {
841   return GST_RTP_HEADER_PAYLOAD_TYPE (rtp->map.data);
842 }
843
844 /**
845  * gst_rtp_buffer_set_payload_type:
846  * @rtp: the RTP packet
847  * @payload_type: the new type
848  *
849  * Set the payload type of the RTP packet in @buffer to @payload_type.
850  */
851 void
852 gst_rtp_buffer_set_payload_type (GstRTPBuffer * rtp, guint8 payload_type)
853 {
854   g_return_if_fail (payload_type < 0x80);
855
856   GST_RTP_HEADER_PAYLOAD_TYPE (rtp->map.data) = payload_type;
857 }
858
859 /**
860  * gst_rtp_buffer_get_seq:
861  * @rtp: the RTP packet
862  *
863  * Get the sequence number of the RTP packet in @buffer.
864  *
865  * Returns: The sequence number in host order.
866  */
867 guint16
868 gst_rtp_buffer_get_seq (GstRTPBuffer * rtp)
869 {
870   return g_ntohs (GST_RTP_HEADER_SEQ (rtp->map.data));
871 }
872
873 /**
874  * gst_rtp_buffer_set_seq:
875  * @rtp: the RTP packet
876  * @seq: the new sequence number
877  *
878  * Set the sequence number of the RTP packet in @buffer to @seq.
879  */
880 void
881 gst_rtp_buffer_set_seq (GstRTPBuffer * rtp, guint16 seq)
882 {
883   GST_RTP_HEADER_SEQ (rtp->map.data) = g_htons (seq);
884 }
885
886 /**
887  * gst_rtp_buffer_get_timestamp:
888  * @rtp: the RTP packet
889  *
890  * Get the timestamp of the RTP packet in @buffer.
891  *
892  * Returns: The timestamp in host order.
893  */
894 guint32
895 gst_rtp_buffer_get_timestamp (GstRTPBuffer * rtp)
896 {
897   return g_ntohl (GST_RTP_HEADER_TIMESTAMP (rtp->map.data));
898 }
899
900 /**
901  * gst_rtp_buffer_set_timestamp:
902  * @rtp: the RTP packet
903  * @timestamp: the new timestamp
904  *
905  * Set the timestamp of the RTP packet in @buffer to @timestamp.
906  */
907 void
908 gst_rtp_buffer_set_timestamp (GstRTPBuffer * rtp, guint32 timestamp)
909 {
910   GST_RTP_HEADER_TIMESTAMP (rtp->map.data) = g_htonl (timestamp);
911 }
912
913
914 /**
915  * gst_rtp_buffer_get_payload_subbuffer:
916  * @rtp: the RTP packet
917  * @offset: the offset in the payload
918  * @len: the length in the payload
919  *
920  * Create a subbuffer of the payload of the RTP packet in @buffer. @offset bytes
921  * are skipped in the payload and the subbuffer will be of size @len.
922  * If @len is -1 the total payload starting from @offset if subbuffered.
923  *
924  * Returns: A new buffer with the specified data of the payload.
925  *
926  * Since: 0.10.10
927  */
928 GstBuffer *
929 gst_rtp_buffer_get_payload_subbuffer (GstRTPBuffer * rtp, guint offset,
930     guint len)
931 {
932   guint poffset, plen;
933
934   plen = gst_rtp_buffer_get_payload_len (rtp);
935   /* we can't go past the length */
936   if (G_UNLIKELY (offset >= plen))
937     goto wrong_offset;
938
939   /* apply offset */
940   poffset = gst_rtp_buffer_get_header_len (rtp) + offset;
941   plen -= offset;
942
943   /* see if we need to shrink the buffer based on @len */
944   if (len != -1 && len < plen)
945     plen = len;
946
947   return gst_buffer_copy_region (rtp->buffer, GST_BUFFER_COPY_ALL, poffset,
948       plen);
949
950   /* ERRORS */
951 wrong_offset:
952   {
953     g_warning ("offset=%u should be less then plen=%u", offset, plen);
954     return NULL;
955   }
956 }
957
958 /**
959  * gst_rtp_buffer_get_payload_buffer:
960  * @rtp: the RTP packet
961  *
962  * Create a buffer of the payload of the RTP packet in @buffer. This function
963  * will internally create a subbuffer of @buffer so that a memcpy can be
964  * avoided.
965  *
966  * Returns: A new buffer with the data of the payload.
967  */
968 GstBuffer *
969 gst_rtp_buffer_get_payload_buffer (GstRTPBuffer * rtp)
970 {
971   return gst_rtp_buffer_get_payload_subbuffer (rtp, 0, -1);
972 }
973
974 /**
975  * gst_rtp_buffer_get_payload_len:
976  * @rtp: the RTP packet
977  *
978  * Get the length of the payload of the RTP packet in @buffer.
979  *
980  * Returns: The length of the payload in @buffer.
981  */
982 guint
983 gst_rtp_buffer_get_payload_len (GstRTPBuffer * rtp)
984 {
985   guint len, size;
986   guint8 *data;
987
988   size = rtp->map.size;
989   data = rtp->map.data;
990
991   len = size - gst_rtp_buffer_get_header_len (rtp);
992
993   if (GST_RTP_HEADER_PADDING (data))
994     len -= data[size - 1];
995
996   return len;
997 }
998
999 /**
1000  * gst_rtp_buffer_get_payload:
1001  * @rtp: the RTP packet
1002  *
1003  * Get a pointer to the payload data in @buffer. This pointer is valid as long
1004  * as a reference to @buffer is held.
1005  *
1006  * Returns: A pointer to the payload data in @buffer.
1007  */
1008 gpointer
1009 gst_rtp_buffer_get_payload (GstRTPBuffer * rtp)
1010 {
1011   return rtp->map.data + gst_rtp_buffer_get_header_len (rtp);
1012 }
1013
1014 /**
1015  * gst_rtp_buffer_default_clock_rate:
1016  * @payload_type: the static payload type
1017  *
1018  * Get the default clock-rate for the static payload type @payload_type.
1019  *
1020  * Returns: the default clock rate or -1 if the payload type is not static or
1021  * the clock-rate is undefined.
1022  *
1023  * Since: 0.10.13
1024  */
1025 guint32
1026 gst_rtp_buffer_default_clock_rate (guint8 payload_type)
1027 {
1028   const GstRTPPayloadInfo *info;
1029   guint32 res;
1030
1031   info = gst_rtp_payload_info_for_pt (payload_type);
1032   if (!info)
1033     return -1;
1034
1035   res = info->clock_rate;
1036   /* 0 means unknown so we have to return -1 from this function */
1037   if (res == 0)
1038     res = -1;
1039
1040   return res;
1041 }
1042
1043 /**
1044  * gst_rtp_buffer_compare_seqnum:
1045  * @seqnum1: a sequence number
1046  * @seqnum2: a sequence number
1047  *
1048  * Compare two sequence numbers, taking care of wraparounds. This function
1049  * returns the difference between @seqnum1 and @seqnum2.
1050  *
1051  * Returns: a negative value if @seqnum1 is bigger than @seqnum2, 0 if they
1052  * are equal or a positive value if @seqnum1 is smaller than @segnum2.
1053  *
1054  * Since: 0.10.15
1055  */
1056 gint
1057 gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2)
1058 {
1059   return (gint16) (seqnum2 - seqnum1);
1060 }
1061
1062 /**
1063  * gst_rtp_buffer_ext_timestamp:
1064  * @exttimestamp: a previous extended timestamp
1065  * @timestamp: a new timestamp
1066  *
1067  * Update the @exttimestamp field with @timestamp. For the first call of the
1068  * method, @exttimestamp should point to a location with a value of -1.
1069  *
1070  * This function makes sure that the returned value is a constantly increasing
1071  * value even in the case where there is a timestamp wraparound.
1072  *
1073  * Returns: The extended timestamp of @timestamp.
1074  *
1075  * Since: 0.10.15
1076  */
1077 guint64
1078 gst_rtp_buffer_ext_timestamp (guint64 * exttimestamp, guint32 timestamp)
1079 {
1080   guint64 result, diff, ext;
1081
1082   g_return_val_if_fail (exttimestamp != NULL, -1);
1083
1084   ext = *exttimestamp;
1085
1086   if (ext == -1) {
1087     result = timestamp;
1088   } else {
1089     /* pick wraparound counter from previous timestamp and add to new timestamp */
1090     result = timestamp + (ext & ~(G_GINT64_CONSTANT (0xffffffff)));
1091
1092     /* check for timestamp wraparound */
1093     if (result < ext)
1094       diff = ext - result;
1095     else
1096       diff = result - ext;
1097
1098     if (diff > G_MAXINT32) {
1099       /* timestamp went backwards more than allowed, we wrap around and get
1100        * updated extended timestamp. */
1101       result += (G_GINT64_CONSTANT (1) << 32);
1102     }
1103   }
1104   *exttimestamp = result;
1105
1106   return result;
1107 }
1108
1109 /**
1110  * gst_rtp_buffer_get_extension_onebyte_header:
1111  * @rtp: the RTP packet
1112  * @id: The ID of the header extension to be read (between 1 and 14).
1113  * @nth: Read the nth extension packet with the requested ID
1114  * @data: location for data
1115  * @size: the size of the data in bytes
1116  *
1117  * Parses RFC 5285 style header extensions with a one byte header. It will
1118  * return the nth extension with the requested id.
1119  *
1120  * Returns: TRUE if @buffer had the requested header extension
1121  *
1122  * Since: 0.10.31
1123  */
1124
1125 gboolean
1126 gst_rtp_buffer_get_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
1127     guint nth, gpointer * data, guint * size)
1128 {
1129   guint16 bits;
1130   guint8 *pdata;
1131   guint wordlen;
1132   gulong offset = 0;
1133   guint count = 0;
1134
1135   g_return_val_if_fail (id > 0 && id < 15, FALSE);
1136
1137   if (!gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer) & pdata,
1138           &wordlen))
1139     return FALSE;
1140
1141   if (bits != 0xBEDE)
1142     return FALSE;
1143
1144   for (;;) {
1145     guint8 read_id, read_len;
1146
1147     if (offset + 1 >= wordlen * 4)
1148       break;
1149
1150     read_id = GST_READ_UINT8 (pdata + offset) >> 4;
1151     read_len = (GST_READ_UINT8 (pdata + offset) & 0x0F) + 1;
1152     offset += 1;
1153
1154     /* ID 0 means its padding, skip */
1155     if (read_id == 0)
1156       continue;
1157
1158     /* ID 15 is special and means we should stop parsing */
1159     if (read_id == 15)
1160       break;
1161
1162     /* Ignore extension headers where the size does not fit */
1163     if (offset + read_len > wordlen * 4)
1164       break;
1165
1166     /* If we have the right one */
1167     if (id == read_id) {
1168       if (nth == count) {
1169         if (data)
1170           *data = pdata + offset;
1171         if (size)
1172           *size = read_len;
1173
1174         return TRUE;
1175       }
1176
1177       count++;
1178     }
1179     offset += read_len;
1180
1181     if (offset >= wordlen * 4)
1182       break;
1183   }
1184
1185   return FALSE;
1186 }
1187
1188 /**
1189  * gst_rtp_buffer_get_extension_twobytes_header:
1190  * @rtp: the RTP packet
1191  * @appbits: Application specific bits
1192  * @id: The ID of the header extension to be read (between 1 and 14).
1193  * @nth: Read the nth extension packet with the requested ID
1194  * @data: location for data
1195  * @size: the size of the data in bytes
1196  *
1197  * Parses RFC 5285 style header extensions with a two bytes header. It will
1198  * return the nth extension with the requested id.
1199  *
1200  * Returns: TRUE if @buffer had the requested header extension
1201  *
1202  * Since: 0.10.31
1203  */
1204
1205 gboolean
1206 gst_rtp_buffer_get_extension_twobytes_header (GstRTPBuffer * rtp,
1207     guint8 * appbits, guint8 id, guint nth, gpointer * data, guint * size)
1208 {
1209   guint16 bits;
1210   guint8 *pdata = NULL;
1211   guint wordlen;
1212   guint bytelen;
1213   gulong offset = 0;
1214   guint count = 0;
1215
1216   if (!gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer *) & pdata,
1217           &wordlen))
1218     return FALSE;
1219
1220   if (bits >> 4 != 0x100)
1221     return FALSE;
1222
1223   bytelen = wordlen * 4;
1224
1225   for (;;) {
1226     guint8 read_id, read_len;
1227
1228     if (offset + 2 >= bytelen)
1229       break;
1230
1231     read_id = GST_READ_UINT8 (pdata + offset);
1232     offset += 1;
1233
1234     if (read_id == 0)
1235       continue;
1236
1237     read_len = GST_READ_UINT8 (pdata + offset);
1238     offset += 1;
1239
1240     /* Ignore extension headers where the size does not fit */
1241     if (offset + read_len > bytelen)
1242       break;
1243
1244     /* If we have the right one, return it */
1245     if (id == read_id) {
1246       if (nth == count) {
1247         if (data)
1248           *data = pdata + offset;
1249         if (size)
1250           *size = read_len;
1251         if (appbits)
1252           *appbits = bits;
1253
1254         return TRUE;
1255       }
1256
1257       count++;
1258     }
1259     offset += read_len;
1260   }
1261
1262   return FALSE;
1263 }
1264
1265 static guint
1266 get_onebyte_header_end_offset (guint8 * pdata, guint wordlen)
1267 {
1268   guint offset = 0;
1269   guint bytelen = wordlen * 4;
1270   guint paddingcount = 0;
1271
1272   while (offset + 1 < bytelen) {
1273     guint8 read_id, read_len;
1274
1275     read_id = GST_READ_UINT8 (pdata + offset) >> 4;
1276     read_len = (GST_READ_UINT8 (pdata + offset) & 0x0F) + 1;
1277     offset += 1;
1278
1279     /* ID 0 means its padding, skip */
1280     if (read_id == 0) {
1281       paddingcount++;
1282       continue;
1283     }
1284
1285     paddingcount = 0;
1286
1287     /* ID 15 is special and means we should stop parsing */
1288     /* It also means we can't add an extra packet */
1289     if (read_id == 15)
1290       return 0;
1291
1292     /* Ignore extension headers where the size does not fit */
1293     if (offset + read_len > bytelen)
1294       return 0;
1295
1296     offset += read_len;
1297   }
1298
1299   return offset - paddingcount;
1300 }
1301
1302 /**
1303  * gst_rtp_buffer_add_extension_onebyte_header:
1304  * @rtp: the RTP packet
1305  * @id: The ID of the header extension (between 1 and 14).
1306  * @data: location for data
1307  * @size: the size of the data in bytes
1308  *
1309  * Adds a RFC 5285 header extension with a one byte header to the end of the
1310  * RTP header. If there is already a RFC 5285 header extension with a one byte
1311  * header, the new extension will be appended.
1312  * It will not work if there is already a header extension that does not follow
1313  * the mecanism described in RFC 5285 or if there is a header extension with
1314  * a two bytes header as described in RFC 5285. In that case, use
1315  * gst_rtp_buffer_add_extension_twobytes_header()
1316  *
1317  * Returns: %TRUE if header extension could be added
1318  *
1319  * Since: 0.10.31
1320  */
1321
1322 gboolean
1323 gst_rtp_buffer_add_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
1324     gpointer data, guint size)
1325 {
1326   guint16 bits;
1327   guint8 *pdata = 0;
1328   guint wordlen;
1329   gboolean has_bit;
1330
1331   g_return_val_if_fail (id > 0 && id < 15, FALSE);
1332   g_return_val_if_fail (size >= 1 && size <= 16, FALSE);
1333   g_return_val_if_fail (gst_buffer_is_writable (rtp->buffer), FALSE);
1334
1335   has_bit = gst_rtp_buffer_get_extension_data (rtp, &bits,
1336       (gpointer) & pdata, &wordlen);
1337
1338   if (has_bit) {
1339     gulong offset = 0;
1340     guint8 *nextext;
1341     guint extlen;
1342
1343     if (bits != 0xBEDE)
1344       return FALSE;
1345
1346     offset = get_onebyte_header_end_offset (pdata, wordlen);
1347     if (offset == 0)
1348       return FALSE;
1349
1350     nextext = pdata + offset;
1351     offset = nextext - rtp->map.data;
1352
1353     /* Don't add extra header if there isn't enough space */
1354     if (rtp->map.size < offset + size + 1)
1355       return FALSE;
1356
1357     nextext[0] = (id << 4) | (0x0F & (size - 1));
1358     memcpy (nextext + 1, data, size);
1359
1360     extlen = nextext - pdata + size + 1;
1361     if (extlen % 4) {
1362       wordlen = extlen / 4 + 1;
1363       memset (nextext + size + 1, 0, 4 - extlen % 4);
1364     } else {
1365       wordlen = extlen / 4;
1366     }
1367
1368     gst_rtp_buffer_set_extension_data (rtp, 0xBEDE, wordlen);
1369   } else {
1370     wordlen = (size + 1) / 4 + (((size + 1) % 4) ? 1 : 0);
1371
1372     gst_rtp_buffer_set_extension_data (rtp, 0xBEDE, wordlen);
1373
1374     gst_rtp_buffer_get_extension_data (rtp, &bits,
1375         (gpointer) & pdata, &wordlen);
1376
1377     pdata[0] = (id << 4) | (0x0F & (size - 1));
1378     memcpy (pdata + 1, data, size);
1379
1380     if ((size + 1) % 4)
1381       memset (pdata + size + 1, 0, 4 - ((size + 1) % 4));
1382   }
1383
1384   return TRUE;
1385 }
1386
1387
1388 static guint
1389 get_twobytes_header_end_offset (guint8 * pdata, guint wordlen)
1390 {
1391   guint offset = 0;
1392   guint bytelen = wordlen * 4;
1393   guint paddingcount = 0;
1394
1395   while (offset + 2 < bytelen) {
1396     guint8 read_id, read_len;
1397
1398     read_id = GST_READ_UINT8 (pdata + offset);
1399     offset += 1;
1400
1401     /* ID 0 means its padding, skip */
1402     if (read_id == 0) {
1403       paddingcount++;
1404       continue;
1405     }
1406
1407     paddingcount = 0;
1408
1409     read_len = GST_READ_UINT8 (pdata + offset);
1410     offset += 1;
1411
1412     /* Ignore extension headers where the size does not fit */
1413     if (offset + read_len > bytelen)
1414       return 0;
1415
1416     offset += read_len;
1417   }
1418
1419   return offset - paddingcount;
1420 }
1421
1422 /**
1423  * gst_rtp_buffer_add_extension_twobytes_header:
1424  * @rtp: the RTP packet
1425  * @appbits: Application specific bits
1426  * @id: The ID of the header extension
1427  * @data: location for data
1428  * @size: the size of the data in bytes
1429  *
1430  * Adds a RFC 5285 header extension with a two bytes header to the end of the
1431  * RTP header. If there is already a RFC 5285 header extension with a two bytes
1432  * header, the new extension will be appended.
1433  * It will not work if there is already a header extension that does not follow
1434  * the mecanism described in RFC 5285 or if there is a header extension with
1435  * a one byte header as described in RFC 5285. In that case, use
1436  * gst_rtp_buffer_add_extension_onebyte_header()
1437  *
1438  * Returns: %TRUE if header extension could be added
1439  *
1440  * Since: 0.10.31
1441  */
1442
1443 gboolean
1444 gst_rtp_buffer_add_extension_twobytes_header (GstRTPBuffer * rtp,
1445     guint8 appbits, guint8 id, gpointer data, guint size)
1446 {
1447   guint16 bits;
1448   guint8 *pdata = 0;
1449   guint wordlen;
1450   gboolean has_bit;
1451
1452   g_return_val_if_fail ((appbits & 0xF0) == 0, FALSE);
1453   g_return_val_if_fail (size < 256, FALSE);
1454   g_return_val_if_fail (gst_buffer_is_writable (rtp->buffer), FALSE);
1455
1456   has_bit = gst_rtp_buffer_get_extension_data (rtp, &bits,
1457       (gpointer) & pdata, &wordlen);
1458
1459   if (has_bit) {
1460     gulong offset = 0;
1461     guint8 *nextext;
1462     guint extlen;
1463
1464     if (bits != ((0x100 << 4) | (appbits & 0x0f)))
1465       return FALSE;
1466
1467     offset = get_twobytes_header_end_offset (pdata, wordlen);
1468
1469     nextext = pdata + offset;
1470
1471     offset = nextext - rtp->map.data;
1472
1473     /* Don't add extra header if there isn't enough space */
1474     if (rtp->map.size < offset + size + 2)
1475       return FALSE;
1476
1477     nextext[0] = id;
1478     nextext[1] = size;
1479     memcpy (nextext + 2, data, size);
1480
1481     extlen = nextext - pdata + size + 2;
1482     if (extlen % 4) {
1483       wordlen = extlen / 4 + 1;
1484       memset (nextext + size + 2, 0, 4 - extlen % 4);
1485     } else {
1486       wordlen = extlen / 4;
1487     }
1488
1489     gst_rtp_buffer_set_extension_data (rtp, (0x100 << 4) | (appbits & 0x0F),
1490         wordlen);
1491   } else {
1492     wordlen = (size + 2) / 4 + (((size + 2) % 4) ? 1 : 0);
1493
1494     gst_rtp_buffer_set_extension_data (rtp, (0x100 << 4) | (appbits & 0x0F),
1495         wordlen);
1496
1497     gst_rtp_buffer_get_extension_data (rtp, &bits,
1498         (gpointer) & pdata, &wordlen);
1499
1500     pdata[0] = id;
1501     pdata[1] = size;
1502     memcpy (pdata + 2, data, size);
1503     if ((size + 2) % 4)
1504       memset (pdata + size + 2, 0, 4 - ((size + 2) % 4));
1505   }
1506
1507   return TRUE;
1508 }