2 * Copyright (C) <2005> Philippe Khalaf <burger@speedy.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "gstrtpbuffer.h"
22 #define GST_RTP_HEADER_LEN 12
24 typedef struct _GstRTPHeader
26 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
27 unsigned int csrc_count:4; /* CSRC count */
28 unsigned int extension:1; /* header extension flag */
29 unsigned int padding:1; /* padding flag */
30 unsigned int version:2; /* protocol version */
31 unsigned int payload_type:7; /* payload type */
32 unsigned int marker:1; /* marker bit */
33 #elif G_BYTE_ORDER == G_BIG_ENDIAN
34 unsigned int version:2; /* protocol version */
35 unsigned int padding:1; /* padding flag */
36 unsigned int extension:1; /* header extension flag */
37 unsigned int csrc_count:4; /* CSRC count */
38 unsigned int marker:1; /* marker bit */
39 unsigned int payload_type:7; /* payload type */
41 #error "G_BYTE_ORDER should be big or little endian."
43 guint16 seq; /* sequence number */
44 guint32 timestamp; /* timestamp */
45 guint32 ssrc; /* synchronization source */
46 guint32 csrc[1]; /* optional CSRC list */
49 #define GST_RTP_HEADER_VERSION(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->version)
50 #define GST_RTP_HEADER_PADDING(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->padding)
51 #define GST_RTP_HEADER_EXTENSION(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->extension)
52 #define GST_RTP_HEADER_CSRC_COUNT(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->csrc_count)
53 #define GST_RTP_HEADER_MARKER(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->marker)
54 #define GST_RTP_HEADER_PAYLOAD_TYPE(buf)(((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->payload_type)
55 #define GST_RTP_HEADER_SEQ(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->seq)
56 #define GST_RTP_HEADER_TIMESTAMP(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->timestamp)
57 #define GST_RTP_HEADER_SSRC(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->ssrc)
58 #define GST_RTP_HEADER_CSRC(buf,i) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->csrc[i])
60 #define GST_RTP_HEADER_CSRC_SIZE(buf) (GST_RTP_HEADER_CSRC_COUNT(buf) * sizeof (guint32))
63 gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
64 guint8 pad_len, guint8 csrc_count)
68 g_return_if_fail (csrc_count <= 15);
69 g_return_if_fail (GST_IS_BUFFER (buffer));
71 len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
72 + payload_len + pad_len;
74 GST_BUFFER_MALLOCDATA (buffer) = g_malloc (len);
75 GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
76 GST_BUFFER_SIZE (buffer) = len;
78 /* fill in defaults */
79 GST_RTP_HEADER_VERSION (buffer) = GST_RTP_VERSION;
80 GST_RTP_HEADER_PADDING (buffer) = FALSE;
81 GST_RTP_HEADER_EXTENSION (buffer) = FALSE;
82 GST_RTP_HEADER_CSRC_COUNT (buffer) = 0;
83 GST_RTP_HEADER_MARKER (buffer) = FALSE;
84 GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = 0;
85 GST_RTP_HEADER_SEQ (buffer) = 0;
86 GST_RTP_HEADER_TIMESTAMP (buffer) = 0;
87 GST_RTP_HEADER_SSRC (buffer) = 0;
91 gst_rtp_buffer_new_take_data (gpointer data, guint len)
95 g_return_val_if_fail (data != NULL, NULL);
96 g_return_val_if_fail (len > 0, NULL);
98 result = gst_buffer_new ();
100 GST_BUFFER_MALLOCDATA (result) = data;
101 GST_BUFFER_DATA (result) = data;
102 GST_BUFFER_SIZE (result) = len;
108 gst_rtp_buffer_new_copy_data (gpointer data, guint len)
110 return gst_rtp_buffer_new_take_data (g_memdup (data, len), len);
114 gst_rtp_buffer_new_allocate (guint payload_len, guint8 pad_len,
119 g_return_val_if_fail (csrc_count <= 15, NULL);
121 result = gst_buffer_new ();
122 gst_rtp_buffer_allocate_data (result, payload_len, pad_len, csrc_count);
128 gst_rtp_buffer_new_allocate_len (guint packet_len, guint8 pad_len,
133 g_return_val_if_fail (csrc_count <= 15, NULL);
135 len = gst_rtp_buffer_calc_payload_len (packet_len, pad_len, csrc_count);
137 return gst_rtp_buffer_new_allocate (len, pad_len, csrc_count);
141 gst_rtp_buffer_calc_header_len (guint8 csrc_count)
143 g_return_val_if_fail (csrc_count <= 15, 0);
145 return GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32));
149 gst_rtp_buffer_calc_packet_len (guint payload_len, guint8 pad_len,
152 g_return_val_if_fail (csrc_count <= 15, 0);
154 return payload_len + GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32))
159 gst_rtp_buffer_calc_payload_len (guint packet_len, guint8 pad_len,
162 g_return_val_if_fail (csrc_count <= 15, 0);
164 return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32))
169 gst_rtp_buffer_validate_data (guint8 * data, guint len)
176 g_return_val_if_fail (data != NULL, FALSE);
178 header_len = GST_RTP_HEADER_LEN;
179 if (len < header_len) {
180 GST_DEBUG ("len < header_len check failed (%d < %d)", len, header_len);
185 version = (data[0] & 0xc0) >> 6;
186 if (version != GST_RTP_VERSION) {
187 GST_DEBUG ("version check failed (%d != %d)", version, GST_RTP_VERSION);
191 /* calc header length with csrc */
192 csrc_count = (data[0] & 0x0f);
193 header_len += csrc_count * sizeof (guint32);
195 /* check for padding */
197 padding = data[len - 1];
201 /* check if padding not bigger than packet and header */
202 if (len - header_len <= padding) {
203 GST_DEBUG ("padding check failed (%d - %d <= %d)",
204 len, header_len, padding);
212 gst_rtp_buffer_validate (GstBuffer * buffer)
217 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
219 data = GST_BUFFER_DATA (buffer);
220 len = GST_BUFFER_SIZE (buffer);
222 return gst_rtp_buffer_validate_data (data, len);
227 gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len)
231 g_return_if_fail (GST_IS_BUFFER (buffer));
233 oldlen = GST_BUFFER_SIZE (buffer);
238 newdata = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len);
239 GST_BUFFER_MALLOCDATA (buffer) = newdata;
240 GST_BUFFER_DATA (buffer) = newdata;
242 GST_BUFFER_SIZE (buffer) = len;
244 /* remove any padding */
245 GST_RTP_HEADER_PADDING (buffer) = FALSE;
250 gst_rtp_buffer_get_packet_len (GstBuffer * buffer)
252 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
254 return GST_BUFFER_SIZE (buffer);
258 gst_rtp_buffer_get_version (GstBuffer * buffer)
260 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
261 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
263 return GST_RTP_HEADER_VERSION (buffer);
267 gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version)
269 g_return_if_fail (GST_IS_BUFFER (buffer));
270 g_return_if_fail (version < 0x04);
271 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
273 GST_RTP_HEADER_VERSION (buffer) = version;
278 gst_rtp_buffer_get_padding (GstBuffer * buffer)
280 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
281 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
283 return GST_RTP_HEADER_PADDING (buffer);
287 gst_rtp_buffer_set_padding (GstBuffer * buffer, gboolean padding)
289 g_return_if_fail (GST_IS_BUFFER (buffer));
290 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
292 GST_RTP_HEADER_PADDING (buffer) = padding;
296 gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len)
298 g_return_if_fail (GST_IS_BUFFER (buffer));
299 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
302 GST_RTP_HEADER_PADDING (buffer) = TRUE;
304 GST_RTP_HEADER_PADDING (buffer) = FALSE;
309 gst_rtp_buffer_get_extension (GstBuffer * buffer)
311 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
312 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
314 return GST_RTP_HEADER_EXTENSION (buffer);
318 gst_rtp_buffer_set_extension (GstBuffer * buffer, gboolean extension)
320 g_return_if_fail (GST_IS_BUFFER (buffer));
321 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
323 GST_RTP_HEADER_EXTENSION (buffer) = extension;
327 gst_rtp_buffer_get_ssrc (GstBuffer * buffer)
329 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
330 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
332 return g_ntohl (GST_RTP_HEADER_SSRC (buffer));
336 gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc)
338 g_return_if_fail (GST_IS_BUFFER (buffer));
339 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
341 GST_RTP_HEADER_SSRC (buffer) = g_htonl (ssrc);
345 gst_rtp_buffer_get_csrc_count (GstBuffer * buffer)
347 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
348 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
350 return GST_RTP_HEADER_CSRC_COUNT (buffer);
354 gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx)
356 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
357 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
358 g_return_val_if_fail (GST_RTP_HEADER_CSRC_COUNT (buffer) < idx, 0);
360 return g_ntohl (GST_RTP_HEADER_CSRC (buffer, idx));
364 gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc)
366 g_return_if_fail (GST_IS_BUFFER (buffer));
367 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
368 g_return_if_fail (GST_RTP_HEADER_CSRC_COUNT (buffer) < idx);
370 GST_RTP_HEADER_CSRC (buffer, idx) = g_htonl (csrc);
374 gst_rtp_buffer_get_marker (GstBuffer * buffer)
376 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
377 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
379 return GST_RTP_HEADER_MARKER (buffer);
383 gst_rtp_buffer_set_marker (GstBuffer * buffer, gboolean marker)
385 g_return_if_fail (GST_IS_BUFFER (buffer));
386 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
388 GST_RTP_HEADER_MARKER (buffer) = marker;
393 gst_rtp_buffer_get_payload_type (GstBuffer * buffer)
395 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
396 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
398 return GST_RTP_HEADER_PAYLOAD_TYPE (buffer);
402 gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type)
404 g_return_if_fail (GST_IS_BUFFER (buffer));
405 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
406 g_return_if_fail (payload_type < 0x80);
408 GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = payload_type;
413 gst_rtp_buffer_get_seq (GstBuffer * buffer)
415 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
416 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
418 return g_ntohs (GST_RTP_HEADER_SEQ (buffer));
422 gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq)
424 g_return_if_fail (GST_IS_BUFFER (buffer));
425 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
427 GST_RTP_HEADER_SEQ (buffer) = g_htons (seq);
432 gst_rtp_buffer_get_timestamp (GstBuffer * buffer)
434 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
435 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
437 return g_ntohl (GST_RTP_HEADER_TIMESTAMP (buffer));
441 gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp)
443 g_return_if_fail (GST_IS_BUFFER (buffer));
444 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
446 GST_RTP_HEADER_TIMESTAMP (buffer) = g_htonl (timestamp);
450 gst_rtp_buffer_get_payload_buffer (GstBuffer * buffer)
454 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
455 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
457 len = gst_rtp_buffer_get_payload_len (buffer);
459 return gst_buffer_create_sub (buffer, GST_RTP_HEADER_LEN
460 + GST_RTP_HEADER_CSRC_SIZE (buffer), len);
464 gst_rtp_buffer_get_payload_len (GstBuffer * buffer)
468 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
469 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
471 len = GST_BUFFER_SIZE (buffer)
472 - GST_RTP_HEADER_LEN - GST_RTP_HEADER_CSRC_SIZE (buffer);
474 if (GST_RTP_HEADER_PADDING (buffer))
475 len -= ((guint8 *) GST_BUFFER_DATA (buffer))[GST_BUFFER_SIZE (buffer) - 1];
481 gst_rtp_buffer_get_payload (GstBuffer * buffer)
483 g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
484 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, NULL);
486 return GST_BUFFER_DATA (buffer) + GST_RTP_HEADER_LEN
487 + GST_RTP_HEADER_CSRC_SIZE (buffer);