|
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(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->version) |
|
73 #define GST_RTP_HEADER_PADDING(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->padding) |
|
74 #define GST_RTP_HEADER_EXTENSION(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->extension) |
|
75 #define GST_RTP_HEADER_CSRC_COUNT(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->csrc_count) |
|
76 #define GST_RTP_HEADER_MARKER(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->marker) |
|
77 #define GST_RTP_HEADER_PAYLOAD_TYPE(buf)(((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->payload_type) |
|
78 #define GST_RTP_HEADER_SEQ(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->seq) |
|
79 #define GST_RTP_HEADER_TIMESTAMP(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->timestamp) |
|
80 #define GST_RTP_HEADER_SSRC(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->ssrc) |
|
81 #define GST_RTP_HEADER_CSRC_LIST_OFFSET(buf,i) \ |
|
82 GST_BUFFER_DATA (buf) + \ |
|
83 G_STRUCT_OFFSET(GstRTPHeader, csrclist) + \ |
|
84 ((i) * sizeof(guint32)) |
|
85 #define GST_RTP_HEADER_CSRC_SIZE(buf) (GST_RTP_HEADER_CSRC_COUNT(buf) * sizeof (guint32)) |
|
86 |
|
87 /** |
|
88 * gst_rtp_buffer_allocate_data: |
|
89 * @buffer: a #GstBuffer |
|
90 * @payload_len: the length of the payload |
|
91 * @pad_len: the amount of padding |
|
92 * @csrc_count: the number of CSRC entries |
|
93 * |
|
94 * Allocate enough data in @buffer to hold an RTP packet with @csrc_count CSRCs, |
|
95 * a payload length of @payload_len and padding of @pad_len. |
|
96 * MALLOCDATA of @buffer will be overwritten and will not be freed. |
|
97 * All other RTP header fields will be set to 0/FALSE. |
|
98 */ |
|
99 #ifdef __SYMBIAN32__ |
|
100 EXPORT_C |
|
101 #endif |
|
102 |
|
103 void |
|
104 gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len, |
|
105 guint8 pad_len, guint8 csrc_count) |
|
106 { |
|
107 guint len; |
|
108 |
|
109 g_return_if_fail (csrc_count <= 15); |
|
110 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
111 |
|
112 len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32) |
|
113 + payload_len + pad_len; |
|
114 |
|
115 GST_BUFFER_MALLOCDATA (buffer) = g_malloc (len); |
|
116 GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer); |
|
117 GST_BUFFER_SIZE (buffer) = len; |
|
118 |
|
119 /* fill in defaults */ |
|
120 GST_RTP_HEADER_VERSION (buffer) = GST_RTP_VERSION; |
|
121 GST_RTP_HEADER_PADDING (buffer) = FALSE; |
|
122 GST_RTP_HEADER_EXTENSION (buffer) = FALSE; |
|
123 GST_RTP_HEADER_CSRC_COUNT (buffer) = csrc_count; |
|
124 memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, 0), 0, |
|
125 csrc_count * sizeof (guint32)); |
|
126 GST_RTP_HEADER_MARKER (buffer) = FALSE; |
|
127 GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = 0; |
|
128 GST_RTP_HEADER_SEQ (buffer) = 0; |
|
129 GST_RTP_HEADER_TIMESTAMP (buffer) = 0; |
|
130 GST_RTP_HEADER_SSRC (buffer) = 0; |
|
131 } |
|
132 |
|
133 /** |
|
134 * gst_rtp_buffer_new_take_data: |
|
135 * @data: data for the new buffer |
|
136 * @len: the length of data |
|
137 * |
|
138 * Create a new buffer and set the data and size of the buffer to @data and @len |
|
139 * respectively. @data will be freed when the buffer is unreffed, so this |
|
140 * function transfers ownership of @data to the new buffer. |
|
141 * |
|
142 * Returns: A newly allocated buffer with @data and of size @len. |
|
143 */ |
|
144 #ifdef __SYMBIAN32__ |
|
145 EXPORT_C |
|
146 #endif |
|
147 |
|
148 GstBuffer * |
|
149 gst_rtp_buffer_new_take_data (gpointer data, guint len) |
|
150 { |
|
151 GstBuffer *result; |
|
152 |
|
153 g_return_val_if_fail (data != NULL, NULL); |
|
154 g_return_val_if_fail (len > 0, NULL); |
|
155 |
|
156 result = gst_buffer_new (); |
|
157 |
|
158 GST_BUFFER_MALLOCDATA (result) = data; |
|
159 GST_BUFFER_DATA (result) = data; |
|
160 GST_BUFFER_SIZE (result) = len; |
|
161 |
|
162 return result; |
|
163 } |
|
164 |
|
165 /** |
|
166 * gst_rtp_buffer_new_copy_data: |
|
167 * @data: data for the new buffer |
|
168 * @len: the length of data |
|
169 * |
|
170 * Create a new buffer and set the data to a copy of @len |
|
171 * bytes of @data and the size to @len. The data will be freed when the buffer |
|
172 * is freed. |
|
173 * |
|
174 * Returns: A newly allocated buffer with a copy of @data and of size @len. |
|
175 */ |
|
176 #ifdef __SYMBIAN32__ |
|
177 EXPORT_C |
|
178 #endif |
|
179 |
|
180 GstBuffer * |
|
181 gst_rtp_buffer_new_copy_data (gpointer data, guint len) |
|
182 { |
|
183 return gst_rtp_buffer_new_take_data (g_memdup (data, len), len); |
|
184 } |
|
185 |
|
186 /** |
|
187 * gst_rtp_buffer_new_allocate: |
|
188 * @payload_len: the length of the payload |
|
189 * @pad_len: the amount of padding |
|
190 * @csrc_count: the number of CSRC entries |
|
191 * |
|
192 * Allocate a new #Gstbuffer with enough data to hold an RTP packet with @csrc_count CSRCs, |
|
193 * a payload length of @payload_len and padding of @pad_len. |
|
194 * All other RTP header fields will be set to 0/FALSE. |
|
195 * |
|
196 * Returns: A newly allocated buffer that can hold an RTP packet with given |
|
197 * parameters. |
|
198 */ |
|
199 #ifdef __SYMBIAN32__ |
|
200 EXPORT_C |
|
201 #endif |
|
202 |
|
203 GstBuffer * |
|
204 gst_rtp_buffer_new_allocate (guint payload_len, guint8 pad_len, |
|
205 guint8 csrc_count) |
|
206 { |
|
207 GstBuffer *result; |
|
208 |
|
209 g_return_val_if_fail (csrc_count <= 15, NULL); |
|
210 |
|
211 result = gst_buffer_new (); |
|
212 gst_rtp_buffer_allocate_data (result, payload_len, pad_len, csrc_count); |
|
213 |
|
214 return result; |
|
215 } |
|
216 |
|
217 /** |
|
218 * gst_rtp_buffer_new_allocate_len: |
|
219 * @packet_len: the total length of the packet |
|
220 * @pad_len: the amount of padding |
|
221 * @csrc_count: the number of CSRC entries |
|
222 * |
|
223 * Create a new #GstBuffer that can hold an RTP packet that is exactly |
|
224 * @packet_len long. The length of the payload depends on @pad_len and |
|
225 * @csrc_count and can be calculated with gst_rtp_buffer_calc_payload_len(). |
|
226 * All RTP header fields will be set to 0/FALSE. |
|
227 * |
|
228 * Returns: A newly allocated buffer that can hold an RTP packet of @packet_len. |
|
229 */ |
|
230 #ifdef __SYMBIAN32__ |
|
231 EXPORT_C |
|
232 #endif |
|
233 |
|
234 GstBuffer * |
|
235 gst_rtp_buffer_new_allocate_len (guint packet_len, guint8 pad_len, |
|
236 guint8 csrc_count) |
|
237 { |
|
238 guint len; |
|
239 |
|
240 g_return_val_if_fail (csrc_count <= 15, NULL); |
|
241 |
|
242 len = gst_rtp_buffer_calc_payload_len (packet_len, pad_len, csrc_count); |
|
243 |
|
244 return gst_rtp_buffer_new_allocate (len, pad_len, csrc_count); |
|
245 } |
|
246 |
|
247 /** |
|
248 * gst_rtp_buffer_calc_header_len: |
|
249 * @csrc_count: the number of CSRC entries |
|
250 * |
|
251 * Calculate the header length of an RTP packet with @csrc_count CSRC entries. |
|
252 * An RTP packet can have at most 15 CSRC entries. |
|
253 * |
|
254 * Returns: The length of an RTP header with @csrc_count CSRC entries. |
|
255 */ |
|
256 #ifdef __SYMBIAN32__ |
|
257 EXPORT_C |
|
258 #endif |
|
259 |
|
260 guint |
|
261 gst_rtp_buffer_calc_header_len (guint8 csrc_count) |
|
262 { |
|
263 g_return_val_if_fail (csrc_count <= 15, 0); |
|
264 |
|
265 return GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32)); |
|
266 } |
|
267 |
|
268 /** |
|
269 * gst_rtp_buffer_calc_packet_len: |
|
270 * @payload_len: the length of the payload |
|
271 * @pad_len: the amount of padding |
|
272 * @csrc_count: the number of CSRC entries |
|
273 * |
|
274 * Calculate the total length of an RTP packet with a payload size of @payload_len, |
|
275 * a padding of @pad_len and a @csrc_count CSRC entries. |
|
276 * |
|
277 * Returns: The total length of an RTP header with given parameters. |
|
278 */ |
|
279 #ifdef __SYMBIAN32__ |
|
280 EXPORT_C |
|
281 #endif |
|
282 |
|
283 guint |
|
284 gst_rtp_buffer_calc_packet_len (guint payload_len, guint8 pad_len, |
|
285 guint8 csrc_count) |
|
286 { |
|
287 g_return_val_if_fail (csrc_count <= 15, 0); |
|
288 |
|
289 return payload_len + GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32)) |
|
290 + pad_len; |
|
291 } |
|
292 |
|
293 /** |
|
294 * gst_rtp_buffer_calc_payload_len: |
|
295 * @packet_len: the length of the total RTP packet |
|
296 * @pad_len: the amount of padding |
|
297 * @csrc_count: the number of CSRC entries |
|
298 * |
|
299 * Calculate the length of the payload of an RTP packet with size @packet_len, |
|
300 * a padding of @pad_len and a @csrc_count CSRC entries. |
|
301 * |
|
302 * Returns: The length of the payload of an RTP packet with given parameters. |
|
303 */ |
|
304 #ifdef __SYMBIAN32__ |
|
305 EXPORT_C |
|
306 #endif |
|
307 |
|
308 guint |
|
309 gst_rtp_buffer_calc_payload_len (guint packet_len, guint8 pad_len, |
|
310 guint8 csrc_count) |
|
311 { |
|
312 g_return_val_if_fail (csrc_count <= 15, 0); |
|
313 |
|
314 return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32)) |
|
315 - pad_len; |
|
316 } |
|
317 |
|
318 /** |
|
319 * gst_rtp_buffer_validate_data: |
|
320 * @data: the data to validate |
|
321 * @len: the length of @data to validate |
|
322 * |
|
323 * Check if the @data and @size point to the data of a valid RTP packet. |
|
324 * This function checks the length, version and padding of the packet data. |
|
325 * Use this function to validate a packet before using the other functions in |
|
326 * this module. |
|
327 * |
|
328 * Returns: TRUE if the data points to a valid RTP packet. |
|
329 */ |
|
330 #ifdef __SYMBIAN32__ |
|
331 EXPORT_C |
|
332 #endif |
|
333 |
|
334 gboolean |
|
335 gst_rtp_buffer_validate_data (guint8 * data, guint len) |
|
336 { |
|
337 guint8 padding; |
|
338 guint8 csrc_count; |
|
339 guint header_len; |
|
340 guint8 version; |
|
341 |
|
342 g_return_val_if_fail (data != NULL, FALSE); |
|
343 |
|
344 header_len = GST_RTP_HEADER_LEN; |
|
345 if (G_UNLIKELY (len < header_len)) |
|
346 goto wrong_length; |
|
347 |
|
348 /* check version */ |
|
349 version = (data[0] & 0xc0) >> 6; |
|
350 if (G_UNLIKELY (version != GST_RTP_VERSION)) |
|
351 goto wrong_version; |
|
352 |
|
353 /* calc header length with csrc */ |
|
354 csrc_count = (data[0] & 0x0f); |
|
355 header_len += csrc_count * sizeof (guint32); |
|
356 |
|
357 /* calc extension length when present. */ |
|
358 if (data[0] & 0x10) { |
|
359 guint8 *extpos; |
|
360 guint16 extlen; |
|
361 |
|
362 /* this points to the extenstion bits and header length */ |
|
363 extpos = &data[header_len]; |
|
364 |
|
365 /* skip the header and check that we have enough space */ |
|
366 header_len += 4; |
|
367 if (G_UNLIKELY (len < header_len)) |
|
368 goto wrong_length; |
|
369 |
|
370 /* skip id */ |
|
371 extpos += 2; |
|
372 /* read length as the number of 32 bits words */ |
|
373 extlen = GST_READ_UINT16_BE (extpos); |
|
374 |
|
375 header_len += extlen * sizeof (guint32); |
|
376 } |
|
377 |
|
378 /* check for padding */ |
|
379 if (data[0] & 0x20) |
|
380 padding = data[len - 1]; |
|
381 else |
|
382 padding = 0; |
|
383 |
|
384 /* check if padding not bigger than packet and header */ |
|
385 if (G_UNLIKELY (len - header_len < padding)) |
|
386 goto wrong_padding; |
|
387 |
|
388 return TRUE; |
|
389 |
|
390 /* ERRORS */ |
|
391 wrong_length: |
|
392 { |
|
393 GST_DEBUG ("len < header_len check failed (%d < %d)", len, header_len); |
|
394 return FALSE; |
|
395 } |
|
396 wrong_version: |
|
397 { |
|
398 GST_DEBUG ("version check failed (%d != %d)", version, GST_RTP_VERSION); |
|
399 return FALSE; |
|
400 } |
|
401 wrong_padding: |
|
402 { |
|
403 GST_DEBUG ("padding check failed (%d - %d < %d)", len, header_len, padding); |
|
404 return FALSE; |
|
405 } |
|
406 } |
|
407 |
|
408 /** |
|
409 * gst_rtp_buffer_validate: |
|
410 * @buffer: the buffer to validate |
|
411 * |
|
412 * Check if the data pointed to by @buffer is a valid RTP packet using |
|
413 * gst_rtp_buffer_validate_data(). |
|
414 * |
|
415 * Returns: TRUE if @buffer is a valid RTP packet. |
|
416 */ |
|
417 #ifdef __SYMBIAN32__ |
|
418 EXPORT_C |
|
419 #endif |
|
420 |
|
421 gboolean |
|
422 gst_rtp_buffer_validate (GstBuffer * buffer) |
|
423 { |
|
424 guint8 *data; |
|
425 guint len; |
|
426 |
|
427 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
|
428 |
|
429 data = GST_BUFFER_DATA (buffer); |
|
430 len = GST_BUFFER_SIZE (buffer); |
|
431 |
|
432 return gst_rtp_buffer_validate_data (data, len); |
|
433 } |
|
434 |
|
435 /** |
|
436 * gst_rtp_buffer_set_packet_len: |
|
437 * @buffer: the buffer |
|
438 * @len: the new packet length |
|
439 * |
|
440 * Set the total @buffer size to @len. The data in the buffer will be made |
|
441 * larger if needed. Any padding will be removed from the packet. |
|
442 */ |
|
443 #ifdef __SYMBIAN32__ |
|
444 EXPORT_C |
|
445 #endif |
|
446 |
|
447 void |
|
448 gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len) |
|
449 { |
|
450 guint oldlen; |
|
451 |
|
452 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
453 |
|
454 oldlen = GST_BUFFER_SIZE (buffer); |
|
455 |
|
456 if (oldlen < len) { |
|
457 guint8 *newdata; |
|
458 |
|
459 newdata = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len); |
|
460 GST_BUFFER_MALLOCDATA (buffer) = newdata; |
|
461 GST_BUFFER_DATA (buffer) = newdata; |
|
462 } |
|
463 GST_BUFFER_SIZE (buffer) = len; |
|
464 |
|
465 /* remove any padding */ |
|
466 GST_RTP_HEADER_PADDING (buffer) = FALSE; |
|
467 } |
|
468 |
|
469 /** |
|
470 * gst_rtp_buffer_get_packet_len: |
|
471 * @buffer: the buffer |
|
472 * |
|
473 * Return the total length of the packet in @buffer. |
|
474 * |
|
475 * Returns: The total length of the packet in @buffer. |
|
476 */ |
|
477 #ifdef __SYMBIAN32__ |
|
478 EXPORT_C |
|
479 #endif |
|
480 |
|
481 guint |
|
482 gst_rtp_buffer_get_packet_len (GstBuffer * buffer) |
|
483 { |
|
484 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
485 |
|
486 return GST_BUFFER_SIZE (buffer); |
|
487 } |
|
488 |
|
489 /** |
|
490 * gst_rtp_buffer_get_header_len: |
|
491 * @buffer: the buffer |
|
492 * |
|
493 * Return the total length of the header in @buffer. This include the length of |
|
494 * the fixed header, the CSRC list and the extension header. |
|
495 * |
|
496 * Returns: The total length of the header in @buffer. |
|
497 */ |
|
498 #ifdef __SYMBIAN32__ |
|
499 EXPORT_C |
|
500 #endif |
|
501 |
|
502 guint |
|
503 gst_rtp_buffer_get_header_len (GstBuffer * buffer) |
|
504 { |
|
505 guint len; |
|
506 |
|
507 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
508 |
|
509 len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer); |
|
510 if (GST_RTP_HEADER_EXTENSION (buffer)) |
|
511 len += GST_READ_UINT16_BE (GST_BUFFER_DATA (buffer) + len + 2) * 4 + 4; |
|
512 |
|
513 return len; |
|
514 } |
|
515 |
|
516 /** |
|
517 * gst_rtp_buffer_get_version: |
|
518 * @buffer: the buffer |
|
519 * |
|
520 * Get the version number of the RTP packet in @buffer. |
|
521 * |
|
522 * Returns: The version of @buffer. |
|
523 */ |
|
524 #ifdef __SYMBIAN32__ |
|
525 EXPORT_C |
|
526 #endif |
|
527 |
|
528 guint8 |
|
529 gst_rtp_buffer_get_version (GstBuffer * buffer) |
|
530 { |
|
531 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
532 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
|
533 |
|
534 return GST_RTP_HEADER_VERSION (buffer); |
|
535 } |
|
536 |
|
537 /** |
|
538 * gst_rtp_buffer_set_version: |
|
539 * @buffer: the buffer |
|
540 * @version: the new version |
|
541 * |
|
542 * Set the version of the RTP packet in @buffer to @version. |
|
543 */ |
|
544 #ifdef __SYMBIAN32__ |
|
545 EXPORT_C |
|
546 #endif |
|
547 |
|
548 void |
|
549 gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version) |
|
550 { |
|
551 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
552 g_return_if_fail (version < 0x04); |
|
553 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
554 |
|
555 GST_RTP_HEADER_VERSION (buffer) = version; |
|
556 } |
|
557 |
|
558 /** |
|
559 * gst_rtp_buffer_get_padding: |
|
560 * @buffer: the buffer |
|
561 * |
|
562 * Check if the padding bit is set on the RTP packet in @buffer. |
|
563 * |
|
564 * Returns: TRUE if @buffer has the padding bit set. |
|
565 */ |
|
566 #ifdef __SYMBIAN32__ |
|
567 EXPORT_C |
|
568 #endif |
|
569 |
|
570 gboolean |
|
571 gst_rtp_buffer_get_padding (GstBuffer * buffer) |
|
572 { |
|
573 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
|
574 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE); |
|
575 |
|
576 return GST_RTP_HEADER_PADDING (buffer); |
|
577 } |
|
578 |
|
579 /** |
|
580 * gst_rtp_buffer_set_padding: |
|
581 * @buffer: the buffer |
|
582 * @padding: the new padding |
|
583 * |
|
584 * Set the padding bit on the RTP packet in @buffer to @padding. |
|
585 */ |
|
586 #ifdef __SYMBIAN32__ |
|
587 EXPORT_C |
|
588 #endif |
|
589 |
|
590 void |
|
591 gst_rtp_buffer_set_padding (GstBuffer * buffer, gboolean padding) |
|
592 { |
|
593 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
594 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
595 |
|
596 GST_RTP_HEADER_PADDING (buffer) = padding; |
|
597 } |
|
598 |
|
599 /** |
|
600 * gst_rtp_buffer_pad_to: |
|
601 * @buffer: the buffer |
|
602 * @len: the new amount of padding |
|
603 * |
|
604 * Set the amount of padding in the RTP packet in @buffer to |
|
605 * @len. If @len is 0, the padding is removed. |
|
606 * |
|
607 * NOTE: This function does not work correctly. |
|
608 */ |
|
609 #ifdef __SYMBIAN32__ |
|
610 EXPORT_C |
|
611 #endif |
|
612 |
|
613 void |
|
614 gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len) |
|
615 { |
|
616 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
617 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
618 |
|
619 if (len > 0) |
|
620 GST_RTP_HEADER_PADDING (buffer) = TRUE; |
|
621 else |
|
622 GST_RTP_HEADER_PADDING (buffer) = FALSE; |
|
623 |
|
624 /* FIXME, set the padding byte at the end of the payload data */ |
|
625 } |
|
626 |
|
627 /** |
|
628 * gst_rtp_buffer_get_extension: |
|
629 * @buffer: the buffer |
|
630 * |
|
631 * Check if the extension bit is set on the RTP packet in @buffer. |
|
632 * |
|
633 * Returns: TRUE if @buffer has the extension bit set. |
|
634 */ |
|
635 #ifdef __SYMBIAN32__ |
|
636 EXPORT_C |
|
637 #endif |
|
638 |
|
639 gboolean |
|
640 gst_rtp_buffer_get_extension (GstBuffer * buffer) |
|
641 { |
|
642 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
|
643 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE); |
|
644 |
|
645 return GST_RTP_HEADER_EXTENSION (buffer); |
|
646 } |
|
647 |
|
648 /** |
|
649 * gst_rtp_buffer_set_extension: |
|
650 * @buffer: the buffer |
|
651 * @extension: the new extension |
|
652 * |
|
653 * Set the extension bit on the RTP packet in @buffer to @extension. |
|
654 */ |
|
655 #ifdef __SYMBIAN32__ |
|
656 EXPORT_C |
|
657 #endif |
|
658 |
|
659 void |
|
660 gst_rtp_buffer_set_extension (GstBuffer * buffer, gboolean extension) |
|
661 { |
|
662 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
663 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
664 |
|
665 GST_RTP_HEADER_EXTENSION (buffer) = extension; |
|
666 } |
|
667 |
|
668 /** |
|
669 * gst_rtp_buffer_get_extension_data: |
|
670 * @buffer: the buffer |
|
671 * @bits: location for result bits |
|
672 * @data: location for data |
|
673 * @wordlen: location for length of @data in 32 bits words |
|
674 * |
|
675 * Get the extension data. @bits will contain the extension 16 bits of custom |
|
676 * data. @data will point to the data in the extension and @wordlen will contain |
|
677 * the length of @data in 32 bits words. |
|
678 * |
|
679 * If @buffer did not contain an extension, this function will return %FALSE |
|
680 * with @bits, @data and @wordlen unchanged. |
|
681 * |
|
682 * Returns: TRUE if @buffer had the extension bit set. |
|
683 * |
|
684 * Since: 0.10.15 |
|
685 */ |
|
686 #ifdef __SYMBIAN32__ |
|
687 EXPORT_C |
|
688 #endif |
|
689 |
|
690 gboolean |
|
691 gst_rtp_buffer_get_extension_data (GstBuffer * buffer, guint16 * bits, |
|
692 gpointer * data, guint * wordlen) |
|
693 { |
|
694 guint len; |
|
695 guint8 *pdata; |
|
696 |
|
697 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
|
698 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE); |
|
699 |
|
700 if (!GST_RTP_HEADER_EXTENSION (buffer)) |
|
701 return FALSE; |
|
702 |
|
703 /* move to the extension */ |
|
704 len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer); |
|
705 pdata = GST_BUFFER_DATA (buffer) + len; |
|
706 |
|
707 if (bits) |
|
708 *bits = GST_READ_UINT16_BE (pdata); |
|
709 if (wordlen) |
|
710 *wordlen = GST_READ_UINT16_BE (pdata + 2); |
|
711 if (data) |
|
712 *data = pdata + 4; |
|
713 |
|
714 return TRUE; |
|
715 } |
|
716 |
|
717 /** |
|
718 * gst_rtp_buffer_set_extension_data: |
|
719 * @buffer: the buffer |
|
720 * @bits: the bits specific for the extension |
|
721 * @length: the length that counts the number of 32-bit words in |
|
722 * the extension, excluding the extension header ( therefore zero is a valid length) |
|
723 * |
|
724 * Set the extension bit of the rtp buffer and fill in the @bits and @length of the |
|
725 * extension header. It will refuse to set the extension data if the buffer is not |
|
726 * large enough. |
|
727 * |
|
728 * Returns: True if done. |
|
729 * |
|
730 * Since : 0.10.18 |
|
731 */ |
|
732 #ifdef __SYMBIAN32__ |
|
733 EXPORT_C |
|
734 #endif |
|
735 |
|
736 gboolean |
|
737 gst_rtp_buffer_set_extension_data (GstBuffer * buffer, guint16 bits, |
|
738 guint16 length) |
|
739 { |
|
740 guint32 min_size = 0; |
|
741 guint8 *data; |
|
742 |
|
743 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
|
744 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE); |
|
745 |
|
746 gst_rtp_buffer_set_extension (buffer, TRUE); |
|
747 min_size = |
|
748 GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer) + 4 + |
|
749 length * sizeof (guint32); |
|
750 |
|
751 if (min_size > GST_BUFFER_SIZE (buffer)) { |
|
752 GST_WARNING_OBJECT (buffer, |
|
753 "rtp buffer too small: need more than %d bytes but only have %d bytes", |
|
754 min_size, GST_BUFFER_SIZE (buffer)); |
|
755 return FALSE; |
|
756 } |
|
757 |
|
758 data = |
|
759 GST_BUFFER_DATA (buffer) + GST_RTP_HEADER_LEN + |
|
760 GST_RTP_HEADER_CSRC_SIZE (buffer); |
|
761 GST_WRITE_UINT16_BE (data, bits); |
|
762 GST_WRITE_UINT16_BE (data + 2, length); |
|
763 return TRUE; |
|
764 } |
|
765 |
|
766 /** |
|
767 * gst_rtp_buffer_get_ssrc: |
|
768 * @buffer: the buffer |
|
769 * |
|
770 * Get the SSRC of the RTP packet in @buffer. |
|
771 * |
|
772 * Returns: the SSRC of @buffer in host order. |
|
773 */ |
|
774 #ifdef __SYMBIAN32__ |
|
775 EXPORT_C |
|
776 #endif |
|
777 |
|
778 guint32 |
|
779 gst_rtp_buffer_get_ssrc (GstBuffer * buffer) |
|
780 { |
|
781 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
782 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
|
783 |
|
784 return g_ntohl (GST_RTP_HEADER_SSRC (buffer)); |
|
785 } |
|
786 |
|
787 /** |
|
788 * gst_rtp_buffer_set_ssrc: |
|
789 * @buffer: the buffer |
|
790 * @ssrc: the new SSRC |
|
791 * |
|
792 * Set the SSRC on the RTP packet in @buffer to @ssrc. |
|
793 */ |
|
794 #ifdef __SYMBIAN32__ |
|
795 EXPORT_C |
|
796 #endif |
|
797 |
|
798 void |
|
799 gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc) |
|
800 { |
|
801 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
802 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
803 |
|
804 GST_RTP_HEADER_SSRC (buffer) = g_htonl (ssrc); |
|
805 } |
|
806 |
|
807 /** |
|
808 * gst_rtp_buffer_get_csrc_count: |
|
809 * @buffer: the buffer |
|
810 * |
|
811 * Get the CSRC count of the RTP packet in @buffer. |
|
812 * |
|
813 * Returns: the CSRC count of @buffer. |
|
814 */ |
|
815 #ifdef __SYMBIAN32__ |
|
816 EXPORT_C |
|
817 #endif |
|
818 |
|
819 guint8 |
|
820 gst_rtp_buffer_get_csrc_count (GstBuffer * buffer) |
|
821 { |
|
822 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
823 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
|
824 |
|
825 return GST_RTP_HEADER_CSRC_COUNT (buffer); |
|
826 } |
|
827 |
|
828 /** |
|
829 * gst_rtp_buffer_get_csrc: |
|
830 * @buffer: the buffer |
|
831 * @idx: the index of the CSRC to get |
|
832 * |
|
833 * Get the CSRC at index @idx in @buffer. |
|
834 * |
|
835 * Returns: the CSRC at index @idx in host order. |
|
836 */ |
|
837 #ifdef __SYMBIAN32__ |
|
838 EXPORT_C |
|
839 #endif |
|
840 |
|
841 guint32 |
|
842 gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx) |
|
843 { |
|
844 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
845 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
|
846 g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (buffer), 0); |
|
847 |
|
848 return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, idx)); |
|
849 } |
|
850 |
|
851 /** |
|
852 * gst_rtp_buffer_set_csrc: |
|
853 * @buffer: the buffer |
|
854 * @idx: the CSRC index to set |
|
855 * @csrc: the CSRC in host order to set at @idx |
|
856 * |
|
857 * Modify the CSRC at index @idx in @buffer to @csrc. |
|
858 */ |
|
859 #ifdef __SYMBIAN32__ |
|
860 EXPORT_C |
|
861 #endif |
|
862 |
|
863 void |
|
864 gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc) |
|
865 { |
|
866 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
867 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
868 g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (buffer)); |
|
869 |
|
870 GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, idx), csrc); |
|
871 } |
|
872 |
|
873 /** |
|
874 * gst_rtp_buffer_get_marker: |
|
875 * @buffer: the buffer |
|
876 * |
|
877 * Check if the marker bit is set on the RTP packet in @buffer. |
|
878 * |
|
879 * Returns: TRUE if @buffer has the marker bit set. |
|
880 */ |
|
881 #ifdef __SYMBIAN32__ |
|
882 EXPORT_C |
|
883 #endif |
|
884 |
|
885 gboolean |
|
886 gst_rtp_buffer_get_marker (GstBuffer * buffer) |
|
887 { |
|
888 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
|
889 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE); |
|
890 |
|
891 return GST_RTP_HEADER_MARKER (buffer); |
|
892 } |
|
893 |
|
894 /** |
|
895 * gst_rtp_buffer_set_marker: |
|
896 * @buffer: the buffer |
|
897 * @marker: the new marker |
|
898 * |
|
899 * Set the marker bit on the RTP packet in @buffer to @marker. |
|
900 */ |
|
901 #ifdef __SYMBIAN32__ |
|
902 EXPORT_C |
|
903 #endif |
|
904 |
|
905 void |
|
906 gst_rtp_buffer_set_marker (GstBuffer * buffer, gboolean marker) |
|
907 { |
|
908 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
909 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
910 |
|
911 GST_RTP_HEADER_MARKER (buffer) = marker; |
|
912 } |
|
913 |
|
914 /** |
|
915 * gst_rtp_buffer_get_payload_type: |
|
916 * @buffer: the buffer |
|
917 * |
|
918 * Get the payload type of the RTP packet in @buffer. |
|
919 * |
|
920 * Returns: The payload type. |
|
921 */ |
|
922 #ifdef __SYMBIAN32__ |
|
923 EXPORT_C |
|
924 #endif |
|
925 |
|
926 guint8 |
|
927 gst_rtp_buffer_get_payload_type (GstBuffer * buffer) |
|
928 { |
|
929 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
930 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
|
931 |
|
932 return GST_RTP_HEADER_PAYLOAD_TYPE (buffer); |
|
933 } |
|
934 |
|
935 /** |
|
936 * gst_rtp_buffer_set_payload_type: |
|
937 * @buffer: the buffer |
|
938 * @payload_type: the new type |
|
939 * |
|
940 * Set the payload type of the RTP packet in @buffer to @payload_type. |
|
941 */ |
|
942 #ifdef __SYMBIAN32__ |
|
943 EXPORT_C |
|
944 #endif |
|
945 |
|
946 void |
|
947 gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type) |
|
948 { |
|
949 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
950 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
951 g_return_if_fail (payload_type < 0x80); |
|
952 |
|
953 GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = payload_type; |
|
954 } |
|
955 |
|
956 /** |
|
957 * gst_rtp_buffer_get_seq: |
|
958 * @buffer: the buffer |
|
959 * |
|
960 * Get the sequence number of the RTP packet in @buffer. |
|
961 * |
|
962 * Returns: The sequence number in host order. |
|
963 */ |
|
964 #ifdef __SYMBIAN32__ |
|
965 EXPORT_C |
|
966 #endif |
|
967 |
|
968 guint16 |
|
969 gst_rtp_buffer_get_seq (GstBuffer * buffer) |
|
970 { |
|
971 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
972 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
|
973 |
|
974 return g_ntohs (GST_RTP_HEADER_SEQ (buffer)); |
|
975 } |
|
976 |
|
977 /** |
|
978 * gst_rtp_buffer_set_seq: |
|
979 * @buffer: the buffer |
|
980 * @seq: the new sequence number |
|
981 * |
|
982 * Set the sequence number of the RTP packet in @buffer to @seq. |
|
983 */ |
|
984 #ifdef __SYMBIAN32__ |
|
985 EXPORT_C |
|
986 #endif |
|
987 |
|
988 void |
|
989 gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq) |
|
990 { |
|
991 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
992 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
993 |
|
994 GST_RTP_HEADER_SEQ (buffer) = g_htons (seq); |
|
995 } |
|
996 |
|
997 /** |
|
998 * gst_rtp_buffer_get_timestamp: |
|
999 * @buffer: the buffer |
|
1000 * |
|
1001 * Get the timestamp of the RTP packet in @buffer. |
|
1002 * |
|
1003 * Returns: The timestamp in host order. |
|
1004 */ |
|
1005 #ifdef __SYMBIAN32__ |
|
1006 EXPORT_C |
|
1007 #endif |
|
1008 |
|
1009 guint32 |
|
1010 gst_rtp_buffer_get_timestamp (GstBuffer * buffer) |
|
1011 { |
|
1012 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
1013 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
|
1014 |
|
1015 return g_ntohl (GST_RTP_HEADER_TIMESTAMP (buffer)); |
|
1016 } |
|
1017 |
|
1018 /** |
|
1019 * gst_rtp_buffer_set_timestamp: |
|
1020 * @buffer: the buffer |
|
1021 * @timestamp: the new timestamp |
|
1022 * |
|
1023 * Set the timestamp of the RTP packet in @buffer to @timestamp. |
|
1024 */ |
|
1025 #ifdef __SYMBIAN32__ |
|
1026 EXPORT_C |
|
1027 #endif |
|
1028 |
|
1029 void |
|
1030 gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp) |
|
1031 { |
|
1032 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
1033 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
|
1034 |
|
1035 GST_RTP_HEADER_TIMESTAMP (buffer) = g_htonl (timestamp); |
|
1036 } |
|
1037 |
|
1038 /** |
|
1039 * gst_rtp_buffer_get_payload_subbuffer: |
|
1040 * @buffer: the buffer |
|
1041 * @offset: the offset in the payload |
|
1042 * @len: the length in the payload |
|
1043 * |
|
1044 * Create a subbuffer of the payload of the RTP packet in @buffer. @offset bytes |
|
1045 * are skipped in the payload and the subbuffer will be of size @len. |
|
1046 * If @len is -1 the total payload starting from @offset if subbuffered. |
|
1047 * |
|
1048 * Returns: A new buffer with the specified data of the payload. |
|
1049 * |
|
1050 * Since: 0.10.10 |
|
1051 */ |
|
1052 #ifdef __SYMBIAN32__ |
|
1053 EXPORT_C |
|
1054 #endif |
|
1055 |
|
1056 GstBuffer * |
|
1057 gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset, |
|
1058 guint len) |
|
1059 { |
|
1060 guint poffset, plen; |
|
1061 |
|
1062 g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); |
|
1063 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, NULL); |
|
1064 |
|
1065 plen = gst_rtp_buffer_get_payload_len (buffer); |
|
1066 /* we can't go past the length */ |
|
1067 if (G_UNLIKELY (offset >= plen)) { |
|
1068 GST_WARNING ("offset=%u should be less then plen=%u", offset, plen); |
|
1069 return (NULL); |
|
1070 } |
|
1071 |
|
1072 /* apply offset */ |
|
1073 poffset = gst_rtp_buffer_get_header_len (buffer) + offset; |
|
1074 plen -= offset; |
|
1075 |
|
1076 /* see if we need to shrink the buffer based on @len */ |
|
1077 if (len != -1 && len < plen) |
|
1078 plen = len; |
|
1079 |
|
1080 return gst_buffer_create_sub (buffer, poffset, plen); |
|
1081 } |
|
1082 |
|
1083 /** |
|
1084 * gst_rtp_buffer_get_payload_buffer: |
|
1085 * @buffer: the buffer |
|
1086 * |
|
1087 * Create a buffer of the payload of the RTP packet in @buffer. This function |
|
1088 * will internally create a subbuffer of @buffer so that a memcpy can be |
|
1089 * avoided. |
|
1090 * |
|
1091 * Returns: A new buffer with the data of the payload. |
|
1092 */ |
|
1093 #ifdef __SYMBIAN32__ |
|
1094 EXPORT_C |
|
1095 #endif |
|
1096 |
|
1097 GstBuffer * |
|
1098 gst_rtp_buffer_get_payload_buffer (GstBuffer * buffer) |
|
1099 { |
|
1100 return gst_rtp_buffer_get_payload_subbuffer (buffer, 0, -1); |
|
1101 } |
|
1102 |
|
1103 /** |
|
1104 * gst_rtp_buffer_get_payload_len: |
|
1105 * @buffer: the buffer |
|
1106 * |
|
1107 * Get the length of the payload of the RTP packet in @buffer. |
|
1108 * |
|
1109 * Returns: The length of the payload in @buffer. |
|
1110 */ |
|
1111 #ifdef __SYMBIAN32__ |
|
1112 EXPORT_C |
|
1113 #endif |
|
1114 |
|
1115 guint |
|
1116 gst_rtp_buffer_get_payload_len (GstBuffer * buffer) |
|
1117 { |
|
1118 guint len, size; |
|
1119 |
|
1120 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
1121 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
|
1122 |
|
1123 size = GST_BUFFER_SIZE (buffer); |
|
1124 |
|
1125 len = size - gst_rtp_buffer_get_header_len (buffer); |
|
1126 |
|
1127 if (GST_RTP_HEADER_PADDING (buffer)) |
|
1128 len -= GST_BUFFER_DATA (buffer)[size - 1]; |
|
1129 |
|
1130 return len; |
|
1131 } |
|
1132 |
|
1133 /** |
|
1134 * gst_rtp_buffer_get_payload: |
|
1135 * @buffer: the buffer |
|
1136 * |
|
1137 * Get a pointer to the payload data in @buffer. This pointer is valid as long |
|
1138 * as a reference to @buffer is held. |
|
1139 * |
|
1140 * Returns: A pointer to the payload data in @buffer. |
|
1141 */ |
|
1142 #ifdef __SYMBIAN32__ |
|
1143 EXPORT_C |
|
1144 #endif |
|
1145 |
|
1146 gpointer |
|
1147 gst_rtp_buffer_get_payload (GstBuffer * buffer) |
|
1148 { |
|
1149 g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); |
|
1150 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, NULL); |
|
1151 |
|
1152 return GST_BUFFER_DATA (buffer) + gst_rtp_buffer_get_header_len (buffer); |
|
1153 } |
|
1154 |
|
1155 /** |
|
1156 * gst_rtp_buffer_default_clock_rate: |
|
1157 * @payload_type: the static payload type |
|
1158 * |
|
1159 * Get the default clock-rate for the static payload type @payload_type. |
|
1160 * |
|
1161 * Returns: the default clock rate or -1 if the payload type is not static or |
|
1162 * the clock-rate is undefined. |
|
1163 * |
|
1164 * Since: 0.10.13 |
|
1165 */ |
|
1166 #ifdef __SYMBIAN32__ |
|
1167 EXPORT_C |
|
1168 #endif |
|
1169 |
|
1170 guint32 |
|
1171 gst_rtp_buffer_default_clock_rate (guint8 payload_type) |
|
1172 { |
|
1173 const GstRTPPayloadInfo *info; |
|
1174 guint32 res; |
|
1175 |
|
1176 info = gst_rtp_payload_info_for_pt (payload_type); |
|
1177 if (!info) |
|
1178 return -1; |
|
1179 |
|
1180 res = info->clock_rate; |
|
1181 /* 0 means unknown so we have to return -1 from this function */ |
|
1182 if (res == 0) |
|
1183 res = -1; |
|
1184 |
|
1185 return res; |
|
1186 } |
|
1187 |
|
1188 /** |
|
1189 * gst_rtp_buffer_compare_seqnum: |
|
1190 * @seqnum1: a sequence number |
|
1191 * @seqnum2: a sequence number |
|
1192 * |
|
1193 * Compare two sequence numbers, taking care of wraparounds. |
|
1194 * |
|
1195 * Returns: -1 if @seqnum1 is before @seqnum2, 0 if they are equal or 1 if |
|
1196 * @seqnum1 is bigger than @segnum2. |
|
1197 * |
|
1198 * Since: 0.10.15 |
|
1199 */ |
|
1200 #ifdef __SYMBIAN32__ |
|
1201 EXPORT_C |
|
1202 #endif |
|
1203 |
|
1204 gint |
|
1205 gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2) |
|
1206 { |
|
1207 /* check if diff more than half of the 16bit range */ |
|
1208 if (abs (seqnum2 - seqnum1) > (1 << 15)) { |
|
1209 /* one of a/b has wrapped */ |
|
1210 return seqnum1 - seqnum2; |
|
1211 } else { |
|
1212 return seqnum2 - seqnum1; |
|
1213 } |
|
1214 } |
|
1215 |
|
1216 /** |
|
1217 * gst_rtp_buffer_ext_timestamp: |
|
1218 * @exttimestamp: a previous extended timestamp |
|
1219 * @timestamp: a new timestamp |
|
1220 * |
|
1221 * Update the @exttimestamp field with @timestamp. For the first call of the |
|
1222 * method, @exttimestamp should point to a location with a value of -1. |
|
1223 * |
|
1224 * This function makes sure that the returned value is a constantly increasing |
|
1225 * value even in the case where there is a timestamp wraparound. |
|
1226 * |
|
1227 * Returns: The extended timestamp of @timestamp. |
|
1228 * |
|
1229 * Since: 0.10.15 |
|
1230 */ |
|
1231 #ifdef __SYMBIAN32__ |
|
1232 EXPORT_C |
|
1233 #endif |
|
1234 |
|
1235 guint64 |
|
1236 gst_rtp_buffer_ext_timestamp (guint64 * exttimestamp, guint32 timestamp) |
|
1237 { |
|
1238 guint64 result, diff, ext; |
|
1239 |
|
1240 g_return_val_if_fail (exttimestamp != NULL, -1); |
|
1241 |
|
1242 ext = *exttimestamp; |
|
1243 |
|
1244 if (ext == -1) { |
|
1245 result = timestamp; |
|
1246 } else { |
|
1247 /* pick wraparound counter from previous timestamp and add to new timestamp */ |
|
1248 result = timestamp + (ext & ~(G_GINT64_CONSTANT (0xffffffff))); |
|
1249 |
|
1250 /* check for timestamp wraparound */ |
|
1251 if (result < ext) |
|
1252 diff = ext - result; |
|
1253 else |
|
1254 diff = result - ext; |
|
1255 |
|
1256 if (diff > G_MAXINT32) { |
|
1257 /* timestamp went backwards more than allowed, we wrap around and get |
|
1258 * updated extended timestamp. */ |
|
1259 result += (G_GINT64_CONSTANT (1) << 32); |
|
1260 } |
|
1261 } |
|
1262 *exttimestamp = result; |
|
1263 |
|
1264 return result; |
|
1265 } |