67 unsigned int timestamp:32; /* timestamp */ |
67 unsigned int timestamp:32; /* timestamp */ |
68 unsigned int ssrc:32; /* synchronization source */ |
68 unsigned int ssrc:32; /* synchronization source */ |
69 guint8 csrclist[4]; /* optional CSRC list, 32 bits each */ |
69 guint8 csrclist[4]; /* optional CSRC list, 32 bits each */ |
70 } GstRTPHeader; |
70 } GstRTPHeader; |
71 |
71 |
72 #define GST_RTP_HEADER_VERSION(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->version) |
72 #define GST_RTP_HEADER_VERSION(data) (((GstRTPHeader *)(data))->version) |
73 #define GST_RTP_HEADER_PADDING(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->padding) |
73 #define GST_RTP_HEADER_PADDING(data) (((GstRTPHeader *)(data))->padding) |
74 #define GST_RTP_HEADER_EXTENSION(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->extension) |
74 #define GST_RTP_HEADER_EXTENSION(data) (((GstRTPHeader *)(data))->extension) |
75 #define GST_RTP_HEADER_CSRC_COUNT(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->csrc_count) |
75 #define GST_RTP_HEADER_CSRC_COUNT(data) (((GstRTPHeader *)(data))->csrc_count) |
76 #define GST_RTP_HEADER_MARKER(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->marker) |
76 #define GST_RTP_HEADER_MARKER(data) (((GstRTPHeader *)(data))->marker) |
77 #define GST_RTP_HEADER_PAYLOAD_TYPE(buf)(((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->payload_type) |
77 #define GST_RTP_HEADER_PAYLOAD_TYPE(data) (((GstRTPHeader *)(data))->payload_type) |
78 #define GST_RTP_HEADER_SEQ(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->seq) |
78 #define GST_RTP_HEADER_SEQ(data) (((GstRTPHeader *)(data))->seq) |
79 #define GST_RTP_HEADER_TIMESTAMP(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->timestamp) |
79 #define GST_RTP_HEADER_TIMESTAMP(data) (((GstRTPHeader *)(data))->timestamp) |
80 #define GST_RTP_HEADER_SSRC(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->ssrc) |
80 #define GST_RTP_HEADER_SSRC(data) (((GstRTPHeader *)(data))->ssrc) |
81 #define GST_RTP_HEADER_CSRC_LIST_OFFSET(buf,i) \ |
81 #define GST_RTP_HEADER_CSRC_LIST_OFFSET(data,i) \ |
82 GST_BUFFER_DATA (buf) + \ |
82 data + G_STRUCT_OFFSET(GstRTPHeader, csrclist) + \ |
83 G_STRUCT_OFFSET(GstRTPHeader, csrclist) + \ |
|
84 ((i) * sizeof(guint32)) |
83 ((i) * sizeof(guint32)) |
85 #define GST_RTP_HEADER_CSRC_SIZE(buf) (GST_RTP_HEADER_CSRC_COUNT(buf) * sizeof (guint32)) |
84 #define GST_RTP_HEADER_CSRC_SIZE(data) (GST_RTP_HEADER_CSRC_COUNT(data) * sizeof (guint32)) |
86 |
85 |
87 /** |
86 /** |
88 * gst_rtp_buffer_allocate_data: |
87 * gst_rtp_buffer_allocate_data: |
89 * @buffer: a #GstBuffer |
88 * @buffer: a #GstBuffer |
90 * @payload_len: the length of the payload |
89 * @payload_len: the length of the payload |
103 void |
102 void |
104 gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len, |
103 gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len, |
105 guint8 pad_len, guint8 csrc_count) |
104 guint8 pad_len, guint8 csrc_count) |
106 { |
105 { |
107 guint len; |
106 guint len; |
|
107 guint8 *data; |
108 |
108 |
109 g_return_if_fail (csrc_count <= 15); |
109 g_return_if_fail (csrc_count <= 15); |
110 g_return_if_fail (GST_IS_BUFFER (buffer)); |
110 g_return_if_fail (GST_IS_BUFFER (buffer)); |
111 |
111 |
112 len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32) |
112 len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32) |
113 + payload_len + pad_len; |
113 + payload_len + pad_len; |
114 |
114 |
115 GST_BUFFER_MALLOCDATA (buffer) = g_malloc (len); |
115 data = g_malloc (len); |
116 GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer); |
116 GST_BUFFER_MALLOCDATA (buffer) = data; |
|
117 GST_BUFFER_DATA (buffer) = data; |
117 GST_BUFFER_SIZE (buffer) = len; |
118 GST_BUFFER_SIZE (buffer) = len; |
118 |
119 |
119 /* fill in defaults */ |
120 /* fill in defaults */ |
120 GST_RTP_HEADER_VERSION (buffer) = GST_RTP_VERSION; |
121 GST_RTP_HEADER_VERSION (data) = GST_RTP_VERSION; |
121 GST_RTP_HEADER_PADDING (buffer) = FALSE; |
122 GST_RTP_HEADER_PADDING (data) = FALSE; |
122 GST_RTP_HEADER_EXTENSION (buffer) = FALSE; |
123 GST_RTP_HEADER_EXTENSION (data) = FALSE; |
123 GST_RTP_HEADER_CSRC_COUNT (buffer) = csrc_count; |
124 GST_RTP_HEADER_CSRC_COUNT (data) = csrc_count; |
124 memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, 0), 0, |
125 memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, 0), 0, |
125 csrc_count * sizeof (guint32)); |
126 csrc_count * sizeof (guint32)); |
126 GST_RTP_HEADER_MARKER (buffer) = FALSE; |
127 GST_RTP_HEADER_MARKER (data) = FALSE; |
127 GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = 0; |
128 GST_RTP_HEADER_PAYLOAD_TYPE (data) = 0; |
128 GST_RTP_HEADER_SEQ (buffer) = 0; |
129 GST_RTP_HEADER_SEQ (data) = 0; |
129 GST_RTP_HEADER_TIMESTAMP (buffer) = 0; |
130 GST_RTP_HEADER_TIMESTAMP (data) = 0; |
130 GST_RTP_HEADER_SSRC (buffer) = 0; |
131 GST_RTP_HEADER_SSRC (data) = 0; |
131 } |
132 } |
132 |
133 |
133 /** |
134 /** |
134 * gst_rtp_buffer_new_take_data: |
135 * gst_rtp_buffer_new_take_data: |
135 * @data: data for the new buffer |
136 * @data: data for the new buffer |
314 return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32)) |
315 return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32)) |
315 - pad_len; |
316 - pad_len; |
316 } |
317 } |
317 |
318 |
318 /** |
319 /** |
319 * gst_rtp_buffer_validate_data: |
320 * validate_data: |
320 * @data: the data to validate |
321 * @data: the data to validate |
321 * @len: the length of @data to validate |
322 * @len: the length of @data to validate |
322 * |
323 * @payload: the payload if @data represents the header only |
323 * Check if the @data and @size point to the data of a valid RTP packet. |
324 * @payload_len: the len of the payload |
324 * This function checks the length, version and padding of the packet data. |
325 * |
325 * Use this function to validate a packet before using the other functions in |
326 * Checks if @data is a valid RTP packet. |
326 * this module. |
327 * |
327 * |
328 * Returns: TRUE if @data is a valid RTP packet |
328 * Returns: TRUE if the data points to a valid RTP packet. |
329 */ |
329 */ |
330 static gboolean |
330 #ifdef __SYMBIAN32__ |
331 validate_data (guint8 * data, guint len, guint8 * payload, guint payload_len) |
331 EXPORT_C |
|
332 #endif |
|
333 |
|
334 gboolean |
|
335 gst_rtp_buffer_validate_data (guint8 * data, guint len) |
|
336 { |
332 { |
337 guint8 padding; |
333 guint8 padding; |
338 guint8 csrc_count; |
334 guint8 csrc_count; |
339 guint header_len; |
335 guint header_len; |
340 guint8 version; |
336 guint8 version; |
344 header_len = GST_RTP_HEADER_LEN; |
340 header_len = GST_RTP_HEADER_LEN; |
345 if (G_UNLIKELY (len < header_len)) |
341 if (G_UNLIKELY (len < header_len)) |
346 goto wrong_length; |
342 goto wrong_length; |
347 |
343 |
348 /* check version */ |
344 /* check version */ |
349 version = (data[0] & 0xc0) >> 6; |
345 version = (data[0] & 0xc0); |
350 if (G_UNLIKELY (version != GST_RTP_VERSION)) |
346 if (G_UNLIKELY (version != (GST_RTP_VERSION << 6))) |
351 goto wrong_version; |
347 goto wrong_version; |
352 |
348 |
353 /* calc header length with csrc */ |
349 /* calc header length with csrc */ |
354 csrc_count = (data[0] & 0x0f); |
350 csrc_count = (data[0] & 0x0f); |
355 header_len += csrc_count * sizeof (guint32); |
351 header_len += csrc_count * sizeof (guint32); |
374 |
370 |
375 header_len += extlen * sizeof (guint32); |
371 header_len += extlen * sizeof (guint32); |
376 } |
372 } |
377 |
373 |
378 /* check for padding */ |
374 /* check for padding */ |
379 if (data[0] & 0x20) |
375 if (data[0] & 0x20) { |
380 padding = data[len - 1]; |
376 if (payload) |
381 else |
377 padding = payload[payload_len - 1]; |
|
378 else |
|
379 padding = data[len - 1]; |
|
380 } else { |
382 padding = 0; |
381 padding = 0; |
383 |
382 } |
384 /* check if padding not bigger than packet and header */ |
383 |
385 if (G_UNLIKELY (len - header_len < padding)) |
384 /* check if padding and header not bigger than packet length */ |
|
385 if (G_UNLIKELY (len < padding + header_len)) |
386 goto wrong_padding; |
386 goto wrong_padding; |
387 |
387 |
388 return TRUE; |
388 return TRUE; |
389 |
389 |
390 /* ERRORS */ |
390 /* ERRORS */ |
404 return FALSE; |
404 return FALSE; |
405 } |
405 } |
406 } |
406 } |
407 |
407 |
408 /** |
408 /** |
|
409 * gst_rtp_buffer_validate_data: |
|
410 * @data: the data to validate |
|
411 * @len: the length of @data to validate |
|
412 * |
|
413 * Check if the @data and @size point to the data of a valid RTP packet. |
|
414 * This function checks the length, version and padding of the packet data. |
|
415 * Use this function to validate a packet before using the other functions in |
|
416 * this module. |
|
417 * |
|
418 * Returns: TRUE if the data points to a valid RTP packet. |
|
419 */ |
|
420 #ifdef __SYMBIAN32__ |
|
421 EXPORT_C |
|
422 #endif |
|
423 |
|
424 gboolean |
|
425 gst_rtp_buffer_validate_data (guint8 * data, guint len) |
|
426 { |
|
427 return validate_data (data, len, NULL, 0); |
|
428 } |
|
429 |
|
430 /** |
409 * gst_rtp_buffer_validate: |
431 * gst_rtp_buffer_validate: |
410 * @buffer: the buffer to validate |
432 * @buffer: the buffer to validate |
411 * |
433 * |
412 * Check if the data pointed to by @buffer is a valid RTP packet using |
434 * Check if the data pointed to by @buffer is a valid RTP packet using |
413 * gst_rtp_buffer_validate_data(). |
435 * validate_data(). |
|
436 * Use this function to validate a packet before using the other functions in |
|
437 * this module. |
414 * |
438 * |
415 * Returns: TRUE if @buffer is a valid RTP packet. |
439 * Returns: TRUE if @buffer is a valid RTP packet. |
416 */ |
440 */ |
417 #ifdef __SYMBIAN32__ |
441 #ifdef __SYMBIAN32__ |
418 EXPORT_C |
442 EXPORT_C |
427 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
451 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
428 |
452 |
429 data = GST_BUFFER_DATA (buffer); |
453 data = GST_BUFFER_DATA (buffer); |
430 len = GST_BUFFER_SIZE (buffer); |
454 len = GST_BUFFER_SIZE (buffer); |
431 |
455 |
432 return gst_rtp_buffer_validate_data (data, len); |
456 return validate_data (data, len, NULL, 0); |
|
457 } |
|
458 |
|
459 /** |
|
460 * gst_rtp_buffer_list_validate: |
|
461 * @list: the buffer list to validate |
|
462 * |
|
463 * Check if all RTP packets in the @list are valid using validate_data(). |
|
464 * Use this function to validate an list before using the other functions in |
|
465 * this module. |
|
466 * |
|
467 * Returns: TRUE if @list consists only of valid RTP packets. |
|
468 * |
|
469 * Since: 0.10.24 |
|
470 */ |
|
471 |
|
472 #ifdef __SYMBIAN32__ |
|
473 EXPORT_C |
|
474 #endif |
|
475 |
|
476 gboolean |
|
477 gst_rtp_buffer_list_validate (GstBufferList * list) |
|
478 { |
|
479 guint16 prev_seqnum = 0; |
|
480 GstBufferListIterator *it; |
|
481 guint i = 0; |
|
482 |
|
483 g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE); |
|
484 |
|
485 it = gst_buffer_list_iterate (list); |
|
486 g_return_val_if_fail (it != NULL, FALSE); |
|
487 |
|
488 /* iterate through all the RTP packets in the list */ |
|
489 while (gst_buffer_list_iterator_next_group (it)) { |
|
490 GstBuffer *rtpbuf; |
|
491 GstBuffer *paybuf; |
|
492 guint8 *packet_header; |
|
493 guint8 *packet_payload; |
|
494 guint payload_size; |
|
495 guint packet_size; |
|
496 |
|
497 /* each group should consists of 2 buffers: one containing the RTP header |
|
498 * and the other one the payload, FIXME, relax the requirement of only one |
|
499 * payload buffer. */ |
|
500 if (gst_buffer_list_iterator_n_buffers (it) != 2) |
|
501 goto invalid_list; |
|
502 |
|
503 /* get the RTP header */ |
|
504 rtpbuf = gst_buffer_list_iterator_next (it); |
|
505 packet_header = GST_BUFFER_DATA (rtpbuf); |
|
506 if (packet_header == NULL) |
|
507 goto invalid_list; |
|
508 |
|
509 /* get the payload */ |
|
510 paybuf = gst_buffer_list_iterator_next (it); |
|
511 packet_payload = GST_BUFFER_DATA (paybuf); |
|
512 if (packet_payload == NULL) { |
|
513 goto invalid_list; |
|
514 } |
|
515 payload_size = GST_BUFFER_SIZE (paybuf); |
|
516 if (payload_size == 0) { |
|
517 goto invalid_list; |
|
518 } |
|
519 |
|
520 /* the size of the RTP packet within the current group */ |
|
521 packet_size = GST_BUFFER_SIZE (rtpbuf) + payload_size; |
|
522 |
|
523 /* check the sequence number */ |
|
524 if (G_UNLIKELY (i == 0)) { |
|
525 prev_seqnum = g_ntohs (GST_RTP_HEADER_SEQ (packet_header)); |
|
526 i++; |
|
527 } else { |
|
528 if (++prev_seqnum != g_ntohs (GST_RTP_HEADER_SEQ (packet_header))) |
|
529 goto invalid_list; |
|
530 } |
|
531 |
|
532 /* validate packet */ |
|
533 if (!validate_data (packet_header, packet_size, packet_payload, |
|
534 payload_size)) { |
|
535 goto invalid_list; |
|
536 } |
|
537 } |
|
538 |
|
539 gst_buffer_list_iterator_free (it); |
|
540 |
|
541 return TRUE; |
|
542 |
|
543 /* ERRORS */ |
|
544 invalid_list: |
|
545 { |
|
546 gst_buffer_list_iterator_free (it); |
|
547 return FALSE; |
|
548 } |
433 } |
549 } |
434 |
550 |
435 /** |
551 /** |
436 * gst_rtp_buffer_set_packet_len: |
552 * gst_rtp_buffer_set_packet_len: |
437 * @buffer: the buffer |
553 * @buffer: the buffer |
446 |
562 |
447 void |
563 void |
448 gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len) |
564 gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len) |
449 { |
565 { |
450 guint oldlen; |
566 guint oldlen; |
451 |
567 guint8 *data; |
452 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
453 |
568 |
454 oldlen = GST_BUFFER_SIZE (buffer); |
569 oldlen = GST_BUFFER_SIZE (buffer); |
|
570 data = GST_BUFFER_DATA (buffer); |
455 |
571 |
456 if (oldlen < len) { |
572 if (oldlen < len) { |
457 guint8 *newdata; |
573 data = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len); |
458 |
574 GST_BUFFER_MALLOCDATA (buffer) = data; |
459 newdata = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len); |
575 GST_BUFFER_DATA (buffer) = data; |
460 GST_BUFFER_MALLOCDATA (buffer) = newdata; |
|
461 GST_BUFFER_DATA (buffer) = newdata; |
|
462 } |
576 } |
463 GST_BUFFER_SIZE (buffer) = len; |
577 GST_BUFFER_SIZE (buffer) = len; |
464 |
578 |
465 /* remove any padding */ |
579 /* remove any padding */ |
466 GST_RTP_HEADER_PADDING (buffer) = FALSE; |
580 GST_RTP_HEADER_PADDING (data) = FALSE; |
467 } |
581 } |
468 |
582 |
469 /** |
583 /** |
470 * gst_rtp_buffer_get_packet_len: |
584 * gst_rtp_buffer_get_packet_len: |
471 * @buffer: the buffer |
585 * @buffer: the buffer |
546 #endif |
656 #endif |
547 |
657 |
548 void |
658 void |
549 gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version) |
659 gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version) |
550 { |
660 { |
551 g_return_if_fail (GST_IS_BUFFER (buffer)); |
|
552 g_return_if_fail (version < 0x04); |
661 g_return_if_fail (version < 0x04); |
553 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
662 |
554 |
663 GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer)) = version; |
555 GST_RTP_HEADER_VERSION (buffer) = version; |
|
556 } |
664 } |
557 |
665 |
558 /** |
666 /** |
559 * gst_rtp_buffer_get_padding: |
667 * gst_rtp_buffer_get_padding: |
560 * @buffer: the buffer |
668 * @buffer: the buffer |
611 #endif |
713 #endif |
612 |
714 |
613 void |
715 void |
614 gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len) |
716 gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len) |
615 { |
717 { |
616 g_return_if_fail (GST_IS_BUFFER (buffer)); |
718 guint8 *data; |
617 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
719 |
|
720 data = GST_BUFFER_DATA (buffer); |
618 |
721 |
619 if (len > 0) |
722 if (len > 0) |
620 GST_RTP_HEADER_PADDING (buffer) = TRUE; |
723 GST_RTP_HEADER_PADDING (data) = TRUE; |
621 else |
724 else |
622 GST_RTP_HEADER_PADDING (buffer) = FALSE; |
725 GST_RTP_HEADER_PADDING (data) = FALSE; |
623 |
726 |
624 /* FIXME, set the padding byte at the end of the payload data */ |
727 /* FIXME, set the padding byte at the end of the payload data */ |
625 } |
728 } |
626 |
729 |
627 /** |
730 /** |
692 gpointer * data, guint * wordlen) |
789 gpointer * data, guint * wordlen) |
693 { |
790 { |
694 guint len; |
791 guint len; |
695 guint8 *pdata; |
792 guint8 *pdata; |
696 |
793 |
697 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
794 pdata = GST_BUFFER_DATA (buffer); |
698 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE); |
795 |
699 |
796 if (!GST_RTP_HEADER_EXTENSION (pdata)) |
700 if (!GST_RTP_HEADER_EXTENSION (buffer)) |
|
701 return FALSE; |
797 return FALSE; |
702 |
798 |
703 /* move to the extension */ |
799 /* move to the extension */ |
704 len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer); |
800 len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (pdata); |
705 pdata = GST_BUFFER_DATA (buffer) + len; |
801 pdata += len; |
706 |
802 |
707 if (bits) |
803 if (bits) |
708 *bits = GST_READ_UINT16_BE (pdata); |
804 *bits = GST_READ_UINT16_BE (pdata); |
709 if (wordlen) |
805 if (wordlen) |
710 *wordlen = GST_READ_UINT16_BE (pdata + 2); |
806 *wordlen = GST_READ_UINT16_BE (pdata + 2); |
738 guint16 length) |
834 guint16 length) |
739 { |
835 { |
740 guint32 min_size = 0; |
836 guint32 min_size = 0; |
741 guint8 *data; |
837 guint8 *data; |
742 |
838 |
743 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE); |
839 data = GST_BUFFER_DATA (buffer); |
744 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE); |
840 |
745 |
841 /* check if the buffer is big enough to hold the extension */ |
|
842 min_size = |
|
843 GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data) + 4 + |
|
844 length * sizeof (guint32); |
|
845 if (G_UNLIKELY (min_size > GST_BUFFER_SIZE (buffer))) |
|
846 goto too_small; |
|
847 |
|
848 /* now we can set the extension bit */ |
746 gst_rtp_buffer_set_extension (buffer, TRUE); |
849 gst_rtp_buffer_set_extension (buffer, TRUE); |
747 min_size = |
850 |
748 GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer) + 4 + |
851 data += GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data); |
749 length * sizeof (guint32); |
852 GST_WRITE_UINT16_BE (data, bits); |
750 |
853 GST_WRITE_UINT16_BE (data + 2, length); |
751 if (min_size > GST_BUFFER_SIZE (buffer)) { |
854 |
752 GST_WARNING_OBJECT (buffer, |
855 return TRUE; |
753 "rtp buffer too small: need more than %d bytes but only have %d bytes", |
856 |
|
857 /* ERRORS */ |
|
858 too_small: |
|
859 { |
|
860 g_warning |
|
861 ("rtp buffer too small: need more than %d bytes but only have %d bytes", |
754 min_size, GST_BUFFER_SIZE (buffer)); |
862 min_size, GST_BUFFER_SIZE (buffer)); |
755 return FALSE; |
863 return FALSE; |
756 } |
864 } |
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 } |
865 } |
765 |
866 |
766 /** |
867 /** |
767 * gst_rtp_buffer_get_ssrc: |
868 * gst_rtp_buffer_get_ssrc: |
768 * @buffer: the buffer |
869 * @buffer: the buffer |
776 #endif |
877 #endif |
777 |
878 |
778 guint32 |
879 guint32 |
779 gst_rtp_buffer_get_ssrc (GstBuffer * buffer) |
880 gst_rtp_buffer_get_ssrc (GstBuffer * buffer) |
780 { |
881 { |
781 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
882 return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer))); |
782 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
883 } |
783 |
884 |
784 return g_ntohl (GST_RTP_HEADER_SSRC (buffer)); |
885 /** |
|
886 * gst_rtp_buffer_list_get_ssrc: |
|
887 * @list: the buffer list |
|
888 * |
|
889 * Get the SSRC of the first RTP packet in @list. |
|
890 * All RTP packets within @list have the same SSRC. |
|
891 * |
|
892 * Returns: the SSRC of @list in host order. |
|
893 * |
|
894 * Since: 0.10.24 |
|
895 */ |
|
896 |
|
897 #ifdef __SYMBIAN32__ |
|
898 EXPORT_C |
|
899 #endif |
|
900 |
|
901 guint32 |
|
902 gst_rtp_buffer_list_get_ssrc (GstBufferList * list) |
|
903 { |
|
904 GstBuffer *buffer; |
|
905 |
|
906 buffer = gst_buffer_list_get (list, 0, 0); |
|
907 g_return_val_if_fail (buffer != NULL, 0); |
|
908 |
|
909 return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer))); |
785 } |
910 } |
786 |
911 |
787 /** |
912 /** |
788 * gst_rtp_buffer_set_ssrc: |
913 * gst_rtp_buffer_set_ssrc: |
789 * @buffer: the buffer |
914 * @buffer: the buffer |
796 #endif |
921 #endif |
797 |
922 |
798 void |
923 void |
799 gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc) |
924 gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc) |
800 { |
925 { |
801 g_return_if_fail (GST_IS_BUFFER (buffer)); |
926 GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)) = g_htonl (ssrc); |
802 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
927 } |
803 |
928 |
804 GST_RTP_HEADER_SSRC (buffer) = g_htonl (ssrc); |
929 static GstBufferListItem |
|
930 set_ssrc_header (GstBuffer ** buffer, guint group, guint idx, guint32 * ssrc) |
|
931 { |
|
932 GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (*buffer)) = g_htonl (*ssrc); |
|
933 return GST_BUFFER_LIST_SKIP_GROUP; |
|
934 } |
|
935 |
|
936 /** |
|
937 * gst_rtp_buffer_list_set_ssrc: |
|
938 * @list: the buffer list |
|
939 * @ssrc: the new SSRC |
|
940 * |
|
941 * Set the SSRC on each RTP packet in @list to @ssrc. |
|
942 * |
|
943 * Since: 0.10.24 |
|
944 */ |
|
945 #ifdef __SYMBIAN32__ |
|
946 EXPORT_C |
|
947 #endif |
|
948 void |
|
949 gst_rtp_buffer_list_set_ssrc (GstBufferList * list, guint32 ssrc) |
|
950 { |
|
951 gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc_header, &ssrc); |
805 } |
952 } |
806 |
953 |
807 /** |
954 /** |
808 * gst_rtp_buffer_get_csrc_count: |
955 * gst_rtp_buffer_get_csrc_count: |
809 * @buffer: the buffer |
956 * @buffer: the buffer |
839 #endif |
983 #endif |
840 |
984 |
841 guint32 |
985 guint32 |
842 gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx) |
986 gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx) |
843 { |
987 { |
844 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
988 guint8 *data; |
845 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
989 |
846 g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (buffer), 0); |
990 data = GST_BUFFER_DATA (buffer); |
847 |
991 |
848 return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, idx)); |
992 g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data), 0); |
|
993 |
|
994 return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx)); |
849 } |
995 } |
850 |
996 |
851 /** |
997 /** |
852 * gst_rtp_buffer_set_csrc: |
998 * gst_rtp_buffer_set_csrc: |
853 * @buffer: the buffer |
999 * @buffer: the buffer |
861 #endif |
1007 #endif |
862 |
1008 |
863 void |
1009 void |
864 gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc) |
1010 gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc) |
865 { |
1011 { |
866 g_return_if_fail (GST_IS_BUFFER (buffer)); |
1012 guint8 *data; |
867 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
1013 |
868 g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (buffer)); |
1014 data = GST_BUFFER_DATA (buffer); |
869 |
1015 |
870 GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, idx), csrc); |
1016 g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data)); |
|
1017 |
|
1018 GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx), csrc); |
871 } |
1019 } |
872 |
1020 |
873 /** |
1021 /** |
874 * gst_rtp_buffer_get_marker: |
1022 * gst_rtp_buffer_get_marker: |
875 * @buffer: the buffer |
1023 * @buffer: the buffer |
924 #endif |
1066 #endif |
925 |
1067 |
926 guint8 |
1068 guint8 |
927 gst_rtp_buffer_get_payload_type (GstBuffer * buffer) |
1069 gst_rtp_buffer_get_payload_type (GstBuffer * buffer) |
928 { |
1070 { |
929 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
1071 return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer)); |
930 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
1072 } |
931 |
1073 |
932 return GST_RTP_HEADER_PAYLOAD_TYPE (buffer); |
1074 /** |
|
1075 * gst_rtp_buffer_list_get_payload_type: |
|
1076 * @list: the buffer list |
|
1077 * |
|
1078 * Get the payload type of the first RTP packet in @list. |
|
1079 * All packets in @list should have the same payload type. |
|
1080 * |
|
1081 * Returns: The payload type. |
|
1082 * |
|
1083 * Since: 0.10.24 |
|
1084 */ |
|
1085 |
|
1086 #ifdef __SYMBIAN32__ |
|
1087 EXPORT_C |
|
1088 #endif |
|
1089 |
|
1090 guint8 |
|
1091 gst_rtp_buffer_list_get_payload_type (GstBufferList * list) |
|
1092 { |
|
1093 GstBuffer *buffer; |
|
1094 |
|
1095 buffer = gst_buffer_list_get (list, 0, 0); |
|
1096 g_return_val_if_fail (buffer != NULL, 0); |
|
1097 |
|
1098 return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer)); |
933 } |
1099 } |
934 |
1100 |
935 /** |
1101 /** |
936 * gst_rtp_buffer_set_payload_type: |
1102 * gst_rtp_buffer_set_payload_type: |
937 * @buffer: the buffer |
1103 * @buffer: the buffer |
944 #endif |
1110 #endif |
945 |
1111 |
946 void |
1112 void |
947 gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type) |
1113 gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type) |
948 { |
1114 { |
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); |
1115 g_return_if_fail (payload_type < 0x80); |
952 |
1116 |
953 GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = payload_type; |
1117 GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer)) = payload_type; |
|
1118 } |
|
1119 |
|
1120 static GstBufferListItem |
|
1121 set_pt_header (GstBuffer ** buffer, guint group, guint idx, guint8 * pt) |
|
1122 { |
|
1123 GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (*buffer)) = *pt; |
|
1124 return GST_BUFFER_LIST_SKIP_GROUP; |
|
1125 } |
|
1126 |
|
1127 /** |
|
1128 * gst_rtp_buffer_list_set_payload_type: |
|
1129 * @list: the buffer list |
|
1130 * @payload_type: the new type |
|
1131 * |
|
1132 * Set the payload type of each RTP packet in @list to @payload_type. |
|
1133 * |
|
1134 * Since: 0.10.24 |
|
1135 */ |
|
1136 |
|
1137 #ifdef __SYMBIAN32__ |
|
1138 EXPORT_C |
|
1139 #endif |
|
1140 |
|
1141 void |
|
1142 gst_rtp_buffer_list_set_payload_type (GstBufferList * list, guint8 payload_type) |
|
1143 { |
|
1144 g_return_if_fail (payload_type < 0x80); |
|
1145 |
|
1146 gst_buffer_list_foreach (list, (GstBufferListFunc) set_pt_header, |
|
1147 &payload_type); |
954 } |
1148 } |
955 |
1149 |
956 /** |
1150 /** |
957 * gst_rtp_buffer_get_seq: |
1151 * gst_rtp_buffer_get_seq: |
958 * @buffer: the buffer |
1152 * @buffer: the buffer |
986 #endif |
1177 #endif |
987 |
1178 |
988 void |
1179 void |
989 gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq) |
1180 gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq) |
990 { |
1181 { |
991 g_return_if_fail (GST_IS_BUFFER (buffer)); |
1182 GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)) = g_htons (seq); |
992 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
1183 } |
993 |
1184 |
994 GST_RTP_HEADER_SEQ (buffer) = g_htons (seq); |
1185 static GstBufferListItem |
995 } |
1186 set_seq_header (GstBuffer ** buffer, guint group, guint idx, guint16 * seq) |
|
1187 { |
|
1188 GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (*buffer)) = g_htons (*seq); |
|
1189 (*seq)++; |
|
1190 return GST_BUFFER_LIST_SKIP_GROUP; |
|
1191 } |
|
1192 |
|
1193 /** |
|
1194 * gst_rtp_buffer_list_set_seq: |
|
1195 * @list: the buffer list |
|
1196 * @seq: the new sequence number |
|
1197 * |
|
1198 * Set the sequence number of each RTP packet in @list to @seq. |
|
1199 * |
|
1200 * Returns: The seq number of the last packet in the list + 1. |
|
1201 * |
|
1202 * Since: 0.10.24 |
|
1203 */ |
|
1204 |
|
1205 #ifdef __SYMBIAN32__ |
|
1206 EXPORT_C |
|
1207 #endif |
|
1208 |
|
1209 guint16 |
|
1210 gst_rtp_buffer_list_set_seq (GstBufferList * list, guint16 seq) |
|
1211 { |
|
1212 gst_buffer_list_foreach (list, (GstBufferListFunc) set_seq_header, &seq); |
|
1213 return seq; |
|
1214 } |
|
1215 |
|
1216 /** |
|
1217 * gst_rtp_buffer_list_get_seq: |
|
1218 * @list: the buffer list |
|
1219 * |
|
1220 * Get the sequence number of the first RTP packet in @list. |
|
1221 * All packets within @list have the same sequence number. |
|
1222 * |
|
1223 * Returns: The seq number |
|
1224 * |
|
1225 * Since: 0.10.24 |
|
1226 */ |
|
1227 |
|
1228 #ifdef __SYMBIAN32__ |
|
1229 EXPORT_C |
|
1230 #endif |
|
1231 |
|
1232 guint16 |
|
1233 gst_rtp_buffer_list_get_seq (GstBufferList * list) |
|
1234 { |
|
1235 GstBuffer *buffer; |
|
1236 |
|
1237 buffer = gst_buffer_list_get (list, 0, 0); |
|
1238 g_return_val_if_fail (buffer != NULL, 0); |
|
1239 |
|
1240 return g_ntohl (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer))); |
|
1241 } |
|
1242 |
996 |
1243 |
997 /** |
1244 /** |
998 * gst_rtp_buffer_get_timestamp: |
1245 * gst_rtp_buffer_get_timestamp: |
999 * @buffer: the buffer |
1246 * @buffer: the buffer |
1000 * |
1247 * |
1007 #endif |
1254 #endif |
1008 |
1255 |
1009 guint32 |
1256 guint32 |
1010 gst_rtp_buffer_get_timestamp (GstBuffer * buffer) |
1257 gst_rtp_buffer_get_timestamp (GstBuffer * buffer) |
1011 { |
1258 { |
1012 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
1259 return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer))); |
1013 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
1260 } |
1014 |
1261 |
1015 return g_ntohl (GST_RTP_HEADER_TIMESTAMP (buffer)); |
1262 /** |
|
1263 * gst_rtp_buffer_list_get_timestamp: |
|
1264 * @list: the buffer list |
|
1265 * |
|
1266 * Get the timestamp of the first RTP packet in @list. |
|
1267 * All packets within @list have the same timestamp. |
|
1268 * |
|
1269 * Returns: The timestamp in host order. |
|
1270 * |
|
1271 * Since: 0.10.24 |
|
1272 */ |
|
1273 |
|
1274 #ifdef __SYMBIAN32__ |
|
1275 EXPORT_C |
|
1276 #endif |
|
1277 |
|
1278 guint32 |
|
1279 gst_rtp_buffer_list_get_timestamp (GstBufferList * list) |
|
1280 { |
|
1281 GstBuffer *buffer; |
|
1282 |
|
1283 buffer = gst_buffer_list_get (list, 0, 0); |
|
1284 g_return_val_if_fail (buffer != NULL, 0); |
|
1285 |
|
1286 return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer))); |
1016 } |
1287 } |
1017 |
1288 |
1018 /** |
1289 /** |
1019 * gst_rtp_buffer_set_timestamp: |
1290 * gst_rtp_buffer_set_timestamp: |
1020 * @buffer: the buffer |
1291 * @buffer: the buffer |
1027 #endif |
1298 #endif |
1028 |
1299 |
1029 void |
1300 void |
1030 gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp) |
1301 gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp) |
1031 { |
1302 { |
1032 g_return_if_fail (GST_IS_BUFFER (buffer)); |
1303 GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)) = g_htonl (timestamp); |
1033 g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); |
1304 } |
1034 |
1305 |
1035 GST_RTP_HEADER_TIMESTAMP (buffer) = g_htonl (timestamp); |
1306 |
|
1307 static GstBufferListItem |
|
1308 set_timestamp_header (GstBuffer ** buffer, guint group, guint idx, |
|
1309 guint32 * timestamp) |
|
1310 { |
|
1311 GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (*buffer)) = g_htonl (*timestamp); |
|
1312 return GST_BUFFER_LIST_SKIP_GROUP; |
|
1313 } |
|
1314 |
|
1315 /** |
|
1316 * gst_rtp_buffer_list_set_timestamp: |
|
1317 * @list: the buffer list |
|
1318 * @timestamp: the new timestamp |
|
1319 * |
|
1320 * Set the timestamp of each RTP packet in @list to @timestamp. |
|
1321 * |
|
1322 * Since: 0.10.24 |
|
1323 */ |
|
1324 |
|
1325 #ifdef __SYMBIAN32__ |
|
1326 EXPORT_C |
|
1327 #endif |
|
1328 |
|
1329 void |
|
1330 gst_rtp_buffer_list_set_timestamp (GstBufferList * list, guint32 timestamp) |
|
1331 { |
|
1332 gst_buffer_list_foreach (list, (GstBufferListFunc) set_timestamp_header, |
|
1333 ×tamp); |
1036 } |
1334 } |
1037 |
1335 |
1038 /** |
1336 /** |
1039 * gst_rtp_buffer_get_payload_subbuffer: |
1337 * gst_rtp_buffer_get_payload_subbuffer: |
1040 * @buffer: the buffer |
1338 * @buffer: the buffer |
1057 gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset, |
1355 gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset, |
1058 guint len) |
1356 guint len) |
1059 { |
1357 { |
1060 guint poffset, plen; |
1358 guint poffset, plen; |
1061 |
1359 |
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); |
1360 plen = gst_rtp_buffer_get_payload_len (buffer); |
1066 /* we can't go past the length */ |
1361 /* we can't go past the length */ |
1067 if (G_UNLIKELY (offset >= plen)) { |
1362 if (G_UNLIKELY (offset >= plen)) |
1068 GST_WARNING ("offset=%u should be less then plen=%u", offset, plen); |
1363 goto wrong_offset; |
1069 return (NULL); |
|
1070 } |
|
1071 |
1364 |
1072 /* apply offset */ |
1365 /* apply offset */ |
1073 poffset = gst_rtp_buffer_get_header_len (buffer) + offset; |
1366 poffset = gst_rtp_buffer_get_header_len (buffer) + offset; |
1074 plen -= offset; |
1367 plen -= offset; |
1075 |
1368 |
1076 /* see if we need to shrink the buffer based on @len */ |
1369 /* see if we need to shrink the buffer based on @len */ |
1077 if (len != -1 && len < plen) |
1370 if (len != -1 && len < plen) |
1078 plen = len; |
1371 plen = len; |
1079 |
1372 |
1080 return gst_buffer_create_sub (buffer, poffset, plen); |
1373 return gst_buffer_create_sub (buffer, poffset, plen); |
|
1374 |
|
1375 /* ERRORS */ |
|
1376 wrong_offset: |
|
1377 { |
|
1378 g_warning ("offset=%u should be less then plen=%u", offset, plen); |
|
1379 return NULL; |
|
1380 } |
1081 } |
1381 } |
1082 |
1382 |
1083 /** |
1383 /** |
1084 * gst_rtp_buffer_get_payload_buffer: |
1384 * gst_rtp_buffer_get_payload_buffer: |
1085 * @buffer: the buffer |
1385 * @buffer: the buffer |
1114 |
1414 |
1115 guint |
1415 guint |
1116 gst_rtp_buffer_get_payload_len (GstBuffer * buffer) |
1416 gst_rtp_buffer_get_payload_len (GstBuffer * buffer) |
1117 { |
1417 { |
1118 guint len, size; |
1418 guint len, size; |
1119 |
1419 guint8 *data; |
1120 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); |
|
1121 g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); |
|
1122 |
1420 |
1123 size = GST_BUFFER_SIZE (buffer); |
1421 size = GST_BUFFER_SIZE (buffer); |
|
1422 data = GST_BUFFER_DATA (buffer); |
1124 |
1423 |
1125 len = size - gst_rtp_buffer_get_header_len (buffer); |
1424 len = size - gst_rtp_buffer_get_header_len (buffer); |
1126 |
1425 |
1127 if (GST_RTP_HEADER_PADDING (buffer)) |
1426 if (GST_RTP_HEADER_PADDING (data)) |
1128 len -= GST_BUFFER_DATA (buffer)[size - 1]; |
1427 len -= data[size - 1]; |
|
1428 |
|
1429 return len; |
|
1430 } |
|
1431 |
|
1432 /** |
|
1433 * gst_rtp_buffer_list_get_payload_len: |
|
1434 * @list: the buffer list |
|
1435 * |
|
1436 * Get the length of the payload of the RTP packet in @list. |
|
1437 * |
|
1438 * Returns: The length of the payload in @list. |
|
1439 * |
|
1440 * Since: 0.10.24 |
|
1441 */ |
|
1442 |
|
1443 #ifdef __SYMBIAN32__ |
|
1444 EXPORT_C |
|
1445 #endif |
|
1446 |
|
1447 guint |
|
1448 gst_rtp_buffer_list_get_payload_len (GstBufferList * list) |
|
1449 { |
|
1450 guint len; |
|
1451 GstBufferListIterator *it; |
|
1452 |
|
1453 it = gst_buffer_list_iterate (list); |
|
1454 len = 0; |
|
1455 |
|
1456 while (gst_buffer_list_iterator_next_group (it)) { |
|
1457 guint i; |
|
1458 GstBuffer *buf; |
|
1459 |
|
1460 i = 0; |
|
1461 while ((buf = gst_buffer_list_iterator_next (it))) { |
|
1462 /* skip the RTP header */ |
|
1463 if (!i++) |
|
1464 continue; |
|
1465 /* take the size of the current buffer */ |
|
1466 len += GST_BUFFER_SIZE (buf); |
|
1467 } |
|
1468 } |
|
1469 |
|
1470 gst_buffer_list_iterator_free (it); |
1129 |
1471 |
1130 return len; |
1472 return len; |
1131 } |
1473 } |
1132 |
1474 |
1133 /** |
1475 /** |
1188 /** |
1527 /** |
1189 * gst_rtp_buffer_compare_seqnum: |
1528 * gst_rtp_buffer_compare_seqnum: |
1190 * @seqnum1: a sequence number |
1529 * @seqnum1: a sequence number |
1191 * @seqnum2: a sequence number |
1530 * @seqnum2: a sequence number |
1192 * |
1531 * |
1193 * Compare two sequence numbers, taking care of wraparounds. |
1532 * Compare two sequence numbers, taking care of wraparounds. This function |
1194 * |
1533 * returns the difference between @seqnum1 and @seqnum2. |
1195 * Returns: -1 if @seqnum1 is before @seqnum2, 0 if they are equal or 1 if |
1534 * |
1196 * @seqnum1 is bigger than @segnum2. |
1535 * Returns: a negative value if @seqnum1 is bigger than @seqnum2, 0 if they |
|
1536 * are equal or a positive value if @seqnum1 is smaller than @segnum2. |
1197 * |
1537 * |
1198 * Since: 0.10.15 |
1538 * Since: 0.10.15 |
1199 */ |
1539 */ |
1200 #ifdef __SYMBIAN32__ |
1540 #ifdef __SYMBIAN32__ |
1201 EXPORT_C |
1541 EXPORT_C |
1202 #endif |
1542 #endif |
1203 |
1543 |
1204 gint |
1544 gint |
1205 gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2) |
1545 gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2) |
1206 { |
1546 { |
1207 /* check if diff more than half of the 16bit range */ |
1547 return (gint16) (seqnum2 - seqnum1); |
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 } |
1548 } |
1215 |
1549 |
1216 /** |
1550 /** |
1217 * gst_rtp_buffer_ext_timestamp: |
1551 * gst_rtp_buffer_ext_timestamp: |
1218 * @exttimestamp: a previous extended timestamp |
1552 * @exttimestamp: a previous extended timestamp |