2 * Copyright (C) <2007> Wim Taymans <wim@fluendo.com>
4 * gstrtcpbuffer.h: various helper functions to manipulate buffers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * SECTION:gstrtcpbuffer
25 * @short_description: Helper methods for dealing with RTCP buffers
26 * @see_also: #GstBaseRTPPayload, #GstBaseRTPDepayload, #gstrtpbuffer
28 * Note: The API in this module is not yet declared stable.
32 * The GstRTPCBuffer helper functions makes it easy to parse and create regular
33 * #GstBuffer objects that contain compound RTCP packets. These buffers are typically
34 * of 'application/x-rtcp' #GstCaps.
37 * An RTCP buffer consists of 1 or more #GstRTCPPacket structures that you can
38 * retrieve with gst_rtcp_buffer_get_first_packet(). #GstRTCPPacket acts as a pointer
39 * into the RTCP buffer; you can move to the next packet with
40 * gst_rtcp_packet_move_to_next().
44 * Last reviewed on 2007-03-26 (0.10.13)
51 #include "gstrtcpbuffer.h"
54 * gst_rtcp_buffer_new_take_data:
55 * @data: data for the new buffer
56 * @len: the length of data
58 * Create a new buffer and set the data and size of the buffer to @data and @len
59 * respectively. @data will be freed when the buffer is unreffed, so this
60 * function transfers ownership of @data to the new buffer.
62 * Returns: A newly allocated buffer with @data and of size @len.
65 gst_rtcp_buffer_new_take_data (gpointer data, guint len)
69 g_return_val_if_fail (data != NULL, NULL);
70 g_return_val_if_fail (len > 0, NULL);
72 result = gst_buffer_new ();
74 GST_BUFFER_MALLOCDATA (result) = data;
75 GST_BUFFER_DATA (result) = data;
76 GST_BUFFER_SIZE (result) = len;
82 * gst_rtcp_buffer_new_copy_data:
83 * @data: data for the new buffer
84 * @len: the length of data
86 * Create a new buffer and set the data to a copy of @len
87 * bytes of @data and the size to @len. The data will be freed when the buffer
90 * Returns: A newly allocated buffer with a copy of @data and of size @len.
93 gst_rtcp_buffer_new_copy_data (gpointer data, guint len)
95 return gst_rtcp_buffer_new_take_data (g_memdup (data, len), len);
99 * gst_rtcp_buffer_validate_data:
100 * @data: the data to validate
101 * @len: the length of @data to validate
103 * Check if the @data and @size point to the data of a valid RTCP (compound)
105 * Use this function to validate a packet before using the other functions in
108 * Returns: TRUE if the data points to a valid RTCP packet.
111 gst_rtcp_buffer_validate_data (guint8 * data, guint len)
120 g_return_val_if_fail (data != NULL, FALSE);
122 /* we need 4 bytes for the type and length */
123 if (G_UNLIKELY (len < 4))
126 /* first packet must be RR or SR and version must be 2 */
127 header_mask = ((data[0] << 8) | data[1]) & GST_RTCP_VALID_MASK;
128 if (G_UNLIKELY (header_mask != GST_RTCP_VALID_VALUE))
131 /* no padding when mask succeeds */
138 /* get packet length */
139 header_len = (((data[2] << 8) | data[3]) + 1) << 2;
140 if (data_len < header_len)
143 /* move to next compount packet */
145 data_len -= header_len;
147 /* we are at the end now */
151 /* check version of new packet */
152 version = data[0] & 0xc0;
153 if (version != (GST_RTCP_VERSION << 6))
156 /* padding only allowed on last packet */
157 if ((padding = data[0] & 0x20))
161 /* some leftover bytes, check padding */
166 pad_bytes = data[data_len - 1];
167 if (data_len != pad_bytes)
175 GST_DEBUG ("len check failed");
180 GST_DEBUG ("mask check failed (%04x != %04x)", header_mask,
181 GST_RTCP_VALID_VALUE);
186 GST_DEBUG ("wrong version (%d < 2)", version >> 6);
191 GST_DEBUG ("padding check failed");
197 * gst_rtcp_buffer_validate:
198 * @buffer: the buffer to validate
200 * Check if the data pointed to by @buffer is a valid RTCP packet using
201 * gst_rtcp_buffer_validate_data().
203 * Returns: TRUE if @buffer is a valid RTCP packet.
206 gst_rtcp_buffer_validate (GstBuffer * buffer)
211 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
213 data = GST_BUFFER_DATA (buffer);
214 len = GST_BUFFER_SIZE (buffer);
216 return gst_rtcp_buffer_validate_data (data, len);
220 * gst_rtcp_buffer_new:
221 * @mtu: the maximum mtu size.
223 * Create a new buffer for constructing RTCP packets. The packet will have a
224 * maximum size of @mtu.
226 * Returns: A newly allocated buffer.
229 gst_rtcp_buffer_new (guint mtu)
233 g_return_val_if_fail (mtu > 0, NULL);
235 result = gst_buffer_new ();
236 GST_BUFFER_MALLOCDATA (result) = g_malloc0 (mtu);
237 GST_BUFFER_DATA (result) = GST_BUFFER_MALLOCDATA (result);
238 GST_BUFFER_SIZE (result) = mtu;
244 * gst_rtcp_buffer_end:
245 * @buffer: a buffer with an RTCP packet
247 * Finish @buffer after being constructured. This function is usually called
248 * after gst_rtcp_buffer_new() and after adding the RTCP items to the new buffer.
250 * The function adjusts the size of @buffer with the total length of all the
254 gst_rtcp_buffer_end (GstBuffer * buffer)
256 GstRTCPPacket packet;
258 g_return_if_fail (GST_IS_BUFFER (buffer));
260 /* move to the first free space */
261 if (gst_rtcp_buffer_get_first_packet (buffer, &packet))
262 while (gst_rtcp_packet_move_to_next (&packet));
265 GST_BUFFER_SIZE (buffer) = packet.offset;
269 * gst_rtcp_buffer_get_packet_count:
270 * @buffer: a valid RTCP buffer
272 * Get the number of RTCP packets in @buffer.
274 * Returns: the number of RTCP packets in @buffer.
277 gst_rtcp_buffer_get_packet_count (GstBuffer * buffer)
279 GstRTCPPacket packet;
282 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
285 if (gst_rtcp_buffer_get_first_packet (buffer, &packet)) {
288 } while (gst_rtcp_packet_move_to_next (&packet));
295 * read_packet_header:
298 * Read the packet headers for the packet pointed to by @packet.
300 * Returns: TRUE if @packet pointed to a valid header.
303 read_packet_header (GstRTCPPacket * packet)
309 g_return_val_if_fail (packet != NULL, FALSE);
310 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
312 data = GST_BUFFER_DATA (packet->buffer);
313 size = GST_BUFFER_SIZE (packet->buffer);
315 offset = packet->offset;
317 /* check if we are at the end of the buffer, we add 4 because we also want to
318 * ensure we can read the header. */
319 if (offset + 4 > size)
322 if ((data[offset] & 0xc0) != (GST_RTCP_VERSION << 6))
325 /* read count, type and length */
326 packet->padding = (data[offset] & 0x20) == 0x20;
327 packet->count = data[offset] & 0x1f;
328 packet->type = data[offset + 1];
329 packet->length = (data[offset + 2] << 8) | data[offset + 3];
330 packet->item_offset = 4;
331 packet->item_count = 0;
332 packet->entry_offset = 4;
338 * gst_rtcp_buffer_get_first_packet:
339 * @buffer: a valid RTCP buffer
340 * @packet: a #GstRTCPPacket
342 * Initialize a new #GstRTCPPacket pointer that points to the first packet in
345 * Returns: TRUE if the packet existed in @buffer.
348 gst_rtcp_buffer_get_first_packet (GstBuffer * buffer, GstRTCPPacket * packet)
350 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
351 g_return_val_if_fail (packet != NULL, FALSE);
354 packet->buffer = buffer;
356 packet->type = GST_RTCP_TYPE_INVALID;
358 if (!read_packet_header (packet))
365 * gst_rtcp_packet_move_to_next:
366 * @packet: a #GstRTCPPacket
368 * Move the packet pointer @packet to the next packet in the payload.
369 * Use gst_rtcp_buffer_get_first_packet() to initialize @packet.
371 * Returns: TRUE if @packet is pointing to a valid packet after calling this
375 gst_rtcp_packet_move_to_next (GstRTCPPacket * packet)
377 g_return_val_if_fail (packet != NULL, FALSE);
378 g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, FALSE);
379 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
381 /* if we have a padding or invalid packet, it must be the last,
383 if (packet->type == GST_RTCP_TYPE_INVALID || packet->padding)
386 /* move to next packet. Add 4 because the header is not included in length */
387 packet->offset += (packet->length << 2) + 4;
389 /* try to read new header */
390 if (!read_packet_header (packet))
398 packet->type = GST_RTCP_TYPE_INVALID;
404 * gst_rtcp_buffer_add_packet:
405 * @buffer: a valid RTCP buffer
406 * @type: the #GstRTCPType of the new packet
407 * @packet: pointer to new packet
409 * Add a new packet of @type to @buffer. @packet will point to the newly created
412 * Returns: %TRUE if the packet could be created. This function returns %FALSE
413 * if the max mtu is exceeded for the buffer.
416 gst_rtcp_buffer_add_packet (GstBuffer * buffer, GstRTCPType type,
417 GstRTCPPacket * packet)
423 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
424 g_return_val_if_fail (type != GST_RTCP_TYPE_INVALID, FALSE);
425 g_return_val_if_fail (packet != NULL, FALSE);
427 /* find free space */
428 if (gst_rtcp_buffer_get_first_packet (buffer, packet))
429 while (gst_rtcp_packet_move_to_next (packet));
431 size = GST_BUFFER_SIZE (buffer);
433 /* packet->offset is now pointing to the next free offset in the buffer to
434 * start a compount packet. Next we figure out if we have enough free space in
435 * the buffer to continue. */
437 case GST_RTCP_TYPE_SR:
440 case GST_RTCP_TYPE_RR:
443 case GST_RTCP_TYPE_SDES:
446 case GST_RTCP_TYPE_BYE:
449 case GST_RTCP_TYPE_APP:
452 case GST_RTCP_TYPE_RTPFB:
455 case GST_RTCP_TYPE_PSFB:
461 if (packet->offset + len >= size)
464 data = GST_BUFFER_DATA (buffer) + packet->offset;
466 data[0] = (GST_RTCP_VERSION << 6);
468 /* length is stored in multiples of 32 bit words minus the length of the
470 len = (len - 4) >> 2;
472 data[3] = len & 0xff;
474 /* now try to position to the packet */
475 result = read_packet_header (packet);
482 g_warning ("unknown type %d", type);
492 * gst_rtcp_packet_remove:
493 * @packet: a #GstRTCPPacket
495 * Removes the packet pointed to by @packet and moves pointer to the next one
497 * Returns: TRUE if @packet is pointing to a valid packet after calling this
501 gst_rtcp_packet_remove (GstRTCPPacket * packet)
503 gboolean ret = FALSE;
506 g_return_val_if_fail (packet != NULL, FALSE);
507 g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, FALSE);
509 /* The next packet starts at offset + length + 4 (the header) */
510 offset = packet->offset + (packet->length << 2) + 4;
512 /* Overwrite this packet with the rest of the data */
513 memmove (GST_BUFFER_DATA (packet->buffer) + packet->offset,
514 GST_BUFFER_DATA (packet->buffer) + offset,
515 GST_BUFFER_SIZE (packet->buffer) - offset);
517 /* try to read next header */
518 ret = read_packet_header (packet);
520 packet->type = GST_RTCP_TYPE_INVALID;
526 * gst_rtcp_packet_get_padding:
527 * @packet: a valid #GstRTCPPacket
529 * Get the packet padding of the packet pointed to by @packet.
531 * Returns: If the packet has the padding bit set.
534 gst_rtcp_packet_get_padding (GstRTCPPacket * packet)
536 g_return_val_if_fail (packet != NULL, FALSE);
537 g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, FALSE);
539 return packet->padding;
543 * gst_rtcp_packet_get_type:
544 * @packet: a valid #GstRTCPPacket
546 * Get the packet type of the packet pointed to by @packet.
548 * Returns: The packet type or GST_RTCP_TYPE_INVALID when @packet is not
549 * pointing to a valid packet.
552 gst_rtcp_packet_get_type (GstRTCPPacket * packet)
554 g_return_val_if_fail (packet != NULL, GST_RTCP_TYPE_INVALID);
560 * gst_rtcp_packet_get_count:
561 * @packet: a valid #GstRTCPPacket
563 * Get the count field in @packet.
565 * Returns: The count field in @packet or -1 if @packet does not point to a
569 gst_rtcp_packet_get_count (GstRTCPPacket * packet)
571 g_return_val_if_fail (packet != NULL, -1);
572 g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, -1);
574 return packet->count;
578 * gst_rtcp_packet_get_length:
579 * @packet: a valid #GstRTCPPacket
581 * Get the length field of @packet. This is the length of the packet in
582 * 32-bit words minus one.
584 * Returns: The length field of @packet.
587 gst_rtcp_packet_get_length (GstRTCPPacket * packet)
589 g_return_val_if_fail (packet != NULL, 0);
590 g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, 0);
592 return packet->length;
596 * gst_rtcp_packet_sr_get_sender_info:
597 * @packet: a valid SR #GstRTCPPacket
599 * @ntptime: result NTP time
600 * @rtptime: result RTP time
601 * @packet_count: result packet count
602 * @octet_count: result octect count
604 * Parse the SR sender info and store the values.
607 gst_rtcp_packet_sr_get_sender_info (GstRTCPPacket * packet, guint32 * ssrc,
608 guint64 * ntptime, guint32 * rtptime, guint32 * packet_count,
609 guint32 * octet_count)
613 g_return_if_fail (packet != NULL);
614 g_return_if_fail (packet->type == GST_RTCP_TYPE_SR);
615 g_return_if_fail (GST_IS_BUFFER (packet->buffer));
617 data = GST_BUFFER_DATA (packet->buffer);
620 data += packet->offset + 4;
622 *ssrc = GST_READ_UINT32_BE (data);
625 *ntptime = GST_READ_UINT64_BE (data);
628 *rtptime = GST_READ_UINT32_BE (data);
631 *packet_count = GST_READ_UINT32_BE (data);
634 *octet_count = GST_READ_UINT32_BE (data);
638 * gst_rtcp_packet_sr_set_sender_info:
639 * @packet: a valid SR #GstRTCPPacket
641 * @ntptime: the NTP time
642 * @rtptime: the RTP time
643 * @packet_count: the packet count
644 * @octet_count: the octect count
646 * Set the given values in the SR packet @packet.
649 gst_rtcp_packet_sr_set_sender_info (GstRTCPPacket * packet, guint32 ssrc,
650 guint64 ntptime, guint32 rtptime, guint32 packet_count, guint32 octet_count)
654 g_return_if_fail (packet != NULL);
655 g_return_if_fail (packet->type == GST_RTCP_TYPE_SR);
656 g_return_if_fail (GST_IS_BUFFER (packet->buffer));
658 data = GST_BUFFER_DATA (packet->buffer);
661 data += packet->offset + 4;
662 GST_WRITE_UINT32_BE (data, ssrc);
664 GST_WRITE_UINT64_BE (data, ntptime);
666 GST_WRITE_UINT32_BE (data, rtptime);
668 GST_WRITE_UINT32_BE (data, packet_count);
670 GST_WRITE_UINT32_BE (data, octet_count);
674 * gst_rtcp_packet_rr_get_ssrc:
675 * @packet: a valid RR #GstRTCPPacket
677 * Get the ssrc field of the RR @packet.
682 gst_rtcp_packet_rr_get_ssrc (GstRTCPPacket * packet)
687 g_return_val_if_fail (packet != NULL, 0);
688 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR, 0);
689 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
691 data = GST_BUFFER_DATA (packet->buffer);
694 data += packet->offset + 4;
695 ssrc = GST_READ_UINT32_BE (data);
701 * gst_rtcp_packet_rr_set_ssrc:
702 * @packet: a valid RR #GstRTCPPacket
703 * @ssrc: the SSRC to set
705 * Set the ssrc field of the RR @packet.
708 gst_rtcp_packet_rr_set_ssrc (GstRTCPPacket * packet, guint32 ssrc)
712 g_return_if_fail (packet != NULL);
713 g_return_if_fail (packet->type == GST_RTCP_TYPE_RR);
714 g_return_if_fail (GST_IS_BUFFER (packet->buffer));
716 data = GST_BUFFER_DATA (packet->buffer);
719 data += packet->offset + 4;
720 GST_WRITE_UINT32_BE (data, ssrc);
724 * gst_rtcp_packet_get_rb_count:
725 * @packet: a valid SR or RR #GstRTCPPacket
727 * Get the number of report blocks in @packet.
729 * Returns: The number of report blocks in @packet.
732 gst_rtcp_packet_get_rb_count (GstRTCPPacket * packet)
734 g_return_val_if_fail (packet != NULL, 0);
735 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
736 packet->type == GST_RTCP_TYPE_SR, 0);
737 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
739 return packet->count;
743 * gst_rtcp_packet_get_rb:
744 * @packet: a valid SR or RR #GstRTCPPacket
745 * @nth: the nth report block in @packet
746 * @ssrc: result for data source being reported
747 * @fractionlost: result for fraction lost since last SR/RR
748 * @packetslost: result for the cumululative number of packets lost
749 * @exthighestseq: result for the extended last sequence number received
750 * @jitter: result for the interarrival jitter
751 * @lsr: result for the last SR packet from this source
752 * @dlsr: result for the delay since last SR packet
754 * Parse the values of the @nth report block in @packet and store the result in
758 gst_rtcp_packet_get_rb (GstRTCPPacket * packet, guint nth, guint32 * ssrc,
759 guint8 * fractionlost, gint32 * packetslost, guint32 * exthighestseq,
760 guint32 * jitter, guint32 * lsr, guint32 * dlsr)
765 g_return_if_fail (packet != NULL);
766 g_return_if_fail (packet->type == GST_RTCP_TYPE_RR ||
767 packet->type == GST_RTCP_TYPE_SR);
768 g_return_if_fail (GST_IS_BUFFER (packet->buffer));
770 data = GST_BUFFER_DATA (packet->buffer);
773 data += packet->offset + 4;
774 if (packet->type == GST_RTCP_TYPE_RR)
779 /* move to requested index */
783 *ssrc = GST_READ_UINT32_BE (data);
785 tmp = GST_READ_UINT32_BE (data);
787 *fractionlost = (tmp >> 24);
790 if (tmp & 0x00800000)
794 *packetslost = (gint32) tmp;
798 *exthighestseq = GST_READ_UINT32_BE (data);
801 *jitter = GST_READ_UINT32_BE (data);
804 *lsr = GST_READ_UINT32_BE (data);
807 *dlsr = GST_READ_UINT32_BE (data);
811 * gst_rtcp_packet_add_rb:
812 * @packet: a valid SR or RR #GstRTCPPacket
813 * @ssrc: data source being reported
814 * @fractionlost: fraction lost since last SR/RR
815 * @packetslost: the cumululative number of packets lost
816 * @exthighestseq: the extended last sequence number received
817 * @jitter: the interarrival jitter
818 * @lsr: the last SR packet from this source
819 * @dlsr: the delay since last SR packet
821 * Add a new report block to @packet with the given values.
823 * Returns: %TRUE if the packet was created. This function can return %FALSE if
824 * the max MTU is exceeded or the number of report blocks is greater than
825 * #GST_RTCP_MAX_RB_COUNT.
828 gst_rtcp_packet_add_rb (GstRTCPPacket * packet, guint32 ssrc,
829 guint8 fractionlost, gint32 packetslost, guint32 exthighestseq,
830 guint32 jitter, guint32 lsr, guint32 dlsr)
835 g_return_val_if_fail (packet != NULL, FALSE);
836 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
837 packet->type == GST_RTCP_TYPE_SR, FALSE);
838 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
840 if (packet->count >= GST_RTCP_MAX_RB_COUNT)
843 data = GST_BUFFER_DATA (packet->buffer);
844 size = GST_BUFFER_SIZE (packet->buffer);
847 offset = packet->offset + 4;
848 if (packet->type == GST_RTCP_TYPE_RR)
853 /* move to current index */
854 offset += (packet->count * 24);
856 /* we need 24 free bytes now */
857 if (offset + 24 >= size)
860 /* increment packet count and length */
862 data[packet->offset]++;
864 data[packet->offset + 2] = (packet->length) >> 8;
865 data[packet->offset + 3] = (packet->length) & 0xff;
867 /* move to new report block offset */
870 GST_WRITE_UINT32_BE (data, ssrc);
872 GST_WRITE_UINT32_BE (data, (fractionlost << 24) | (packetslost & 0xffffff));
874 GST_WRITE_UINT32_BE (data, exthighestseq);
876 GST_WRITE_UINT32_BE (data, jitter);
878 GST_WRITE_UINT32_BE (data, lsr);
880 GST_WRITE_UINT32_BE (data, dlsr);
891 * gst_rtcp_packet_set_rb:
892 * @packet: a valid SR or RR #GstRTCPPacket
893 * @nth: the nth report block to set
894 * @ssrc: data source being reported
895 * @fractionlost: fraction lost since last SR/RR
896 * @packetslost: the cumululative number of packets lost
897 * @exthighestseq: the extended last sequence number received
898 * @jitter: the interarrival jitter
899 * @lsr: the last SR packet from this source
900 * @dlsr: the delay since last SR packet
902 * Set the @nth new report block in @packet with the given values.
904 * Note: Not implemented.
907 gst_rtcp_packet_set_rb (GstRTCPPacket * packet, guint nth, guint32 ssrc,
908 guint8 fractionlost, gint32 packetslost, guint32 exthighestseq,
909 guint32 jitter, guint32 lsr, guint32 dlsr)
911 g_return_if_fail (packet != NULL);
912 g_return_if_fail (packet->type == GST_RTCP_TYPE_RR ||
913 packet->type == GST_RTCP_TYPE_SR);
914 g_return_if_fail (GST_IS_BUFFER (packet->buffer));
916 g_warning ("not implemented");
921 * gst_rtcp_packet_sdes_get_item_count:
922 * @packet: a valid SDES #GstRTCPPacket
924 * Get the number of items in the SDES packet @packet.
926 * Returns: The number of items in @packet.
929 gst_rtcp_packet_sdes_get_item_count (GstRTCPPacket * packet)
931 g_return_val_if_fail (packet != NULL, 0);
932 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, 0);
933 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
935 return packet->count;
939 * gst_rtcp_packet_sdes_first_item:
940 * @packet: a valid SDES #GstRTCPPacket
942 * Move to the first SDES item in @packet.
944 * Returns: TRUE if there was a first item.
947 gst_rtcp_packet_sdes_first_item (GstRTCPPacket * packet)
949 g_return_val_if_fail (packet != NULL, FALSE);
950 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
951 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
953 packet->item_offset = 4;
954 packet->item_count = 0;
955 packet->entry_offset = 4;
957 if (packet->count == 0)
964 * gst_rtcp_packet_sdes_next_item:
965 * @packet: a valid SDES #GstRTCPPacket
967 * Move to the next SDES item in @packet.
969 * Returns: TRUE if there was a next item.
972 gst_rtcp_packet_sdes_next_item (GstRTCPPacket * packet)
978 g_return_val_if_fail (packet != NULL, FALSE);
979 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
980 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
982 /* if we are at the last item, we are done */
983 if (packet->item_count == packet->count)
987 data = GST_BUFFER_DATA (packet->buffer);
988 data += packet->offset;
990 offset = packet->item_offset;
995 len = (packet->length << 2);
997 while (offset < len) {
998 if (data[offset] == 0) {
999 /* end of list, round to next 32-bit word */
1000 offset = (offset + 4) & ~3;
1003 offset += data[offset + 1] + 2;
1008 packet->item_offset = offset;
1009 packet->item_count++;
1010 packet->entry_offset = 4;
1016 * gst_rtcp_packet_sdes_get_ssrc:
1017 * @packet: a valid SDES #GstRTCPPacket
1019 * Get the SSRC of the current SDES item.
1021 * Returns: the SSRC of the current item.
1024 gst_rtcp_packet_sdes_get_ssrc (GstRTCPPacket * packet)
1029 g_return_val_if_fail (packet != NULL, 0);
1030 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, 0);
1031 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
1034 data = GST_BUFFER_DATA (packet->buffer);
1035 data += packet->offset;
1037 data += packet->item_offset;
1039 ssrc = GST_READ_UINT32_BE (data);
1045 * gst_rtcp_packet_sdes_first_entry:
1046 * @packet: a valid SDES #GstRTCPPacket
1048 * Move to the first SDES entry in the current item.
1050 * Returns: %TRUE if there was a first entry.
1053 gst_rtcp_packet_sdes_first_entry (GstRTCPPacket * packet)
1058 g_return_val_if_fail (packet != NULL, FALSE);
1059 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
1060 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1063 data = GST_BUFFER_DATA (packet->buffer);
1064 data += packet->offset;
1066 offset = packet->item_offset;
1070 packet->entry_offset = 4;
1073 len = (packet->length << 2);
1077 if (data[offset] == 0)
1084 * gst_rtcp_packet_sdes_next_entry:
1085 * @packet: a valid SDES #GstRTCPPacket
1087 * Move to the next SDES entry in the current item.
1089 * Returns: %TRUE if there was a next entry.
1092 gst_rtcp_packet_sdes_next_entry (GstRTCPPacket * packet)
1095 guint len, offset, item_len;
1097 g_return_val_if_fail (packet != NULL, FALSE);
1098 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
1099 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1102 data = GST_BUFFER_DATA (packet->buffer);
1103 data += packet->offset;
1105 offset = packet->item_offset;
1107 offset += packet->entry_offset;
1109 item_len = data[offset + 1] + 2;
1114 len = (packet->length << 2);
1118 packet->entry_offset += item_len;
1120 /* check for end of list */
1121 if (data[offset] == 0)
1128 * gst_rtcp_packet_sdes_get_entry:
1129 * @packet: a valid SDES #GstRTCPPacket
1130 * @type: result of the entry type
1131 * @len: result length of the entry data
1132 * @data: result entry data
1134 * Get the data of the current SDES item entry. @type (when not NULL) will
1135 * contain the type of the entry. @data (when not NULL) will point to @len
1138 * When @type refers to a text item, @data will point to a UTF8 string. Note
1139 * that this UTF8 string is NOT null-terminated. Use
1140 * gst_rtcp_packet_sdes_copy_entry() to get a null-termined copy of the entry.
1142 * Returns: %TRUE if there was valid data.
1145 gst_rtcp_packet_sdes_get_entry (GstRTCPPacket * packet,
1146 GstRTCPSDESType * type, guint8 * len, guint8 ** data)
1151 g_return_val_if_fail (packet != NULL, FALSE);
1152 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
1153 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1156 bdata = GST_BUFFER_DATA (packet->buffer);
1157 bdata += packet->offset;
1159 offset = packet->item_offset;
1161 offset += packet->entry_offset;
1163 if (bdata[offset] == 0)
1167 *type = bdata[offset];
1169 *len = bdata[offset + 1];
1171 *data = &bdata[offset + 2];
1177 * gst_rtcp_packet_sdes_copy_entry:
1178 * @packet: a valid SDES #GstRTCPPacket
1179 * @type: result of the entry type
1180 * @len: result length of the entry data
1181 * @data: result entry data
1183 * This function is like gst_rtcp_packet_sdes_get_entry() but it returns a
1184 * null-terminated copy of the data instead. use g_free() after usage.
1186 * Returns: %TRUE if there was valid data.
1189 gst_rtcp_packet_sdes_copy_entry (GstRTCPPacket * packet,
1190 GstRTCPSDESType * type, guint8 * len, guint8 ** data)
1195 g_return_val_if_fail (packet != NULL, FALSE);
1196 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
1197 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1199 if (!gst_rtcp_packet_sdes_get_entry (packet, type, &tlen, &tdata))
1205 *data = (guint8 *) g_strndup ((gchar *) tdata, tlen);
1211 * gst_rtcp_packet_sdes_add_item:
1212 * @packet: a valid SDES #GstRTCPPacket
1213 * @ssrc: the SSRC of the new item to add
1215 * Add a new SDES item for @ssrc to @packet.
1217 * Returns: %TRUE if the item could be added, %FALSE if the maximum amount of
1218 * items has been exceeded for the SDES packet or the MTU has been reached.
1221 gst_rtcp_packet_sdes_add_item (GstRTCPPacket * packet, guint32 ssrc)
1226 g_return_val_if_fail (packet != NULL, FALSE);
1227 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
1228 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1230 /* increment item count when possible */
1231 if (packet->count >= GST_RTCP_MAX_SDES_ITEM_COUNT)
1234 /* pretend there is a next packet for the next call */
1237 /* jump over current item */
1238 gst_rtcp_packet_sdes_next_item (packet);
1241 data = GST_BUFFER_DATA (packet->buffer);
1242 size = GST_BUFFER_SIZE (packet->buffer);
1243 data += packet->offset;
1244 /* move to current item */
1245 offset = packet->item_offset;
1247 /* we need 2 free words now */
1248 if (offset + 8 >= size)
1252 GST_WRITE_UINT32_BE (&data[offset], ssrc);
1253 /* write 0 entry with padding */
1254 GST_WRITE_UINT32_BE (&data[offset + 4], 0);
1257 data[0] = (data[0] & 0xe0) | packet->count;
1258 /* update length, we added 2 words */
1259 packet->length += 2;
1260 data[2] = (packet->length) >> 8;
1261 data[3] = (packet->length) & 0xff;
1278 * gst_rtcp_packet_sdes_add_entry:
1279 * @packet: a valid SDES #GstRTCPPacket
1280 * @type: the #GstRTCPSDESType of the SDES entry
1281 * @len: the data length
1284 * Add a new SDES entry to the current item in @packet.
1286 * Returns: %TRUE if the item could be added, %FALSE if the MTU has been
1290 gst_rtcp_packet_sdes_add_entry (GstRTCPPacket * packet, GstRTCPSDESType type,
1291 guint8 len, const guint8 * data)
1294 guint offset, size, padded;
1296 g_return_val_if_fail (packet != NULL, FALSE);
1297 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
1298 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1301 bdata = GST_BUFFER_DATA (packet->buffer);
1302 size = GST_BUFFER_SIZE (packet->buffer);
1303 bdata += packet->offset;
1305 offset = packet->item_offset;
1307 offset += packet->entry_offset;
1309 /* add 1 byte end and up to 3 bytes padding to fill a full 32 bit word */
1310 padded = (offset + 2 + len + 1 + 3) & ~3;
1312 /* we need enough space for type, len, data and padding */
1313 if (packet->offset + padded >= size)
1316 bdata[offset] = type;
1317 bdata[offset + 1] = len;
1318 memcpy (&bdata[offset + 2], data, len);
1319 bdata[offset + 2 + len] = 0;
1321 /* calculate new packet length */
1322 packet->length = (padded - 4) >> 2;
1323 bdata[2] = (packet->length) >> 8;
1324 bdata[3] = (packet->length) & 0xff;
1326 /* position to new next entry */
1327 packet->entry_offset += 2 + len;
1339 * gst_rtcp_packet_bye_get_ssrc_count:
1340 * @packet: a valid BYE #GstRTCPPacket
1342 * Get the number of SSRC fields in @packet.
1344 * Returns: The number of SSRC fields in @packet.
1347 gst_rtcp_packet_bye_get_ssrc_count (GstRTCPPacket * packet)
1349 g_return_val_if_fail (packet != NULL, -1);
1350 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, -1);
1352 return packet->count;
1356 * gst_rtcp_packet_bye_get_nth_ssrc:
1357 * @packet: a valid BYE #GstRTCPPacket
1358 * @nth: the nth SSRC to get
1360 * Get the @nth SSRC of the BYE @packet.
1362 * Returns: The @nth SSRC of @packet.
1365 gst_rtcp_packet_bye_get_nth_ssrc (GstRTCPPacket * packet, guint nth)
1372 g_return_val_if_fail (packet != NULL, 0);
1373 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, 0);
1374 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
1376 /* get amount of sources and check that we don't read too much */
1381 /* get offset in 32-bits words into packet, skip the header */
1383 /* check that we don't go past the packet length */
1384 if (offset > packet->length)
1387 /* scale to bytes */
1389 offset += packet->offset;
1391 /* check if the packet is valid */
1392 if (offset + 4 > GST_BUFFER_SIZE (packet->buffer))
1395 data = GST_BUFFER_DATA (packet->buffer);
1398 ssrc = GST_READ_UINT32_BE (data);
1404 * gst_rtcp_packet_bye_add_ssrc:
1405 * @packet: a valid BYE #GstRTCPPacket
1406 * @ssrc: an SSRC to add
1408 * Add @ssrc to the BYE @packet.
1410 * Returns: %TRUE if the ssrc was added. This function can return %FALSE if
1411 * the max MTU is exceeded or the number of sources blocks is greater than
1412 * #GST_RTCP_MAX_BYE_SSRC_COUNT.
1415 gst_rtcp_packet_bye_add_ssrc (GstRTCPPacket * packet, guint32 ssrc)
1420 g_return_val_if_fail (packet != NULL, FALSE);
1421 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, FALSE);
1422 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1424 if (packet->count >= GST_RTCP_MAX_BYE_SSRC_COUNT)
1427 data = GST_BUFFER_DATA (packet->buffer);
1428 size = GST_BUFFER_SIZE (packet->buffer);
1431 offset = packet->offset + 4;
1433 /* move to current index */
1434 offset += (packet->count * 4);
1436 if (offset + 4 >= size)
1439 /* increment packet count and length */
1441 data[packet->offset]++;
1442 packet->length += 1;
1443 data[packet->offset + 2] = (packet->length) >> 8;
1444 data[packet->offset + 3] = (packet->length) & 0xff;
1446 /* move to new SSRC offset and write ssrc */
1448 GST_WRITE_UINT32_BE (data, ssrc);
1460 * gst_rtcp_packet_bye_add_ssrcs:
1461 * @packet: a valid BYE #GstRTCPPacket
1462 * @ssrc: an array of SSRCs to add
1463 * @len: number of elements in @ssrc
1465 * Adds @len SSRCs in @ssrc to BYE @packet.
1467 * Returns: %TRUE if the all the SSRCs were added. This function can return %FALSE if
1468 * the max MTU is exceeded or the number of sources blocks is greater than
1469 * #GST_RTCP_MAX_BYE_SSRC_COUNT.
1472 gst_rtcp_packet_bye_add_ssrcs (GstRTCPPacket * packet, guint32 * ssrc,
1478 g_return_val_if_fail (packet != NULL, FALSE);
1479 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, FALSE);
1480 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1483 for (i = 0; i < len && res; i++) {
1484 res = gst_rtcp_packet_bye_add_ssrc (packet, ssrc[i]);
1489 /* get the offset in packet of the reason length */
1491 get_reason_offset (GstRTCPPacket * packet)
1495 /* get amount of sources plus header */
1496 offset = 1 + packet->count;
1498 /* check that we don't go past the packet length */
1499 if (offset > packet->length)
1502 /* scale to bytes */
1504 offset += packet->offset;
1506 /* check if the packet is valid */
1507 if (offset + 1 > GST_BUFFER_SIZE (packet->buffer))
1514 * gst_rtcp_packet_bye_get_reason_len:
1515 * @packet: a valid BYE #GstRTCPPacket
1517 * Get the length of the reason string.
1519 * Returns: The length of the reason string or 0 when there is no reason string
1523 gst_rtcp_packet_bye_get_reason_len (GstRTCPPacket * packet)
1528 g_return_val_if_fail (packet != NULL, 0);
1529 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, 0);
1530 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
1532 roffset = get_reason_offset (packet);
1536 data = GST_BUFFER_DATA (packet->buffer);
1538 return data[roffset];
1542 * gst_rtcp_packet_bye_get_reason:
1543 * @packet: a valid BYE #GstRTCPPacket
1545 * Get the reason in @packet.
1547 * Returns: The reason for the BYE @packet or NULL if the packet did not contain
1548 * a reason string. The string must be freed with g_free() after usage.
1551 gst_rtcp_packet_bye_get_reason (GstRTCPPacket * packet)
1557 g_return_val_if_fail (packet != NULL, NULL);
1558 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, NULL);
1559 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), NULL);
1561 roffset = get_reason_offset (packet);
1565 data = GST_BUFFER_DATA (packet->buffer);
1567 /* get length of reason string */
1568 len = data[roffset];
1572 /* move to string */
1575 /* check if enough data to copy */
1576 if (roffset + len > GST_BUFFER_SIZE (packet->buffer))
1579 return g_strndup ((gconstpointer) (data + roffset), len);
1583 * gst_rtcp_packet_bye_set_reason:
1584 * @packet: a valid BYE #GstRTCPPacket
1585 * @reason: a reason string
1587 * Set the reason string to @reason in @packet.
1589 * Returns: TRUE if the string could be set.
1592 gst_rtcp_packet_bye_set_reason (GstRTCPPacket * packet, const gchar * reason)
1595 guint roffset, size;
1598 g_return_val_if_fail (packet != NULL, FALSE);
1599 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, FALSE);
1600 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1605 len = strlen (reason);
1609 /* make room for the string before we get the offset */
1612 roffset = get_reason_offset (packet);
1616 data = GST_BUFFER_DATA (packet->buffer);
1617 size = GST_BUFFER_SIZE (packet->buffer);
1619 /* we have 1 byte length and we need to pad to 4 bytes */
1620 padded = ((len + 1) + 3) & ~3;
1622 /* we need enough space for the padded length */
1623 if (roffset + padded >= size)
1626 data[roffset] = len;
1627 memcpy (&data[roffset + 1], reason, len);
1629 /* update packet length, we made room for 1 double word already */
1630 packet->length += (padded >> 2) - 1;
1631 data[packet->offset + 2] = (packet->length) >> 8;
1632 data[packet->offset + 3] = (packet->length) & 0xff;
1645 * gst_rtcp_packet_fb_get_sender_ssrc:
1646 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
1648 * Get the sender SSRC field of the RTPFB or PSFB @packet.
1650 * Returns: the sender SSRC.
1655 gst_rtcp_packet_fb_get_sender_ssrc (GstRTCPPacket * packet)
1660 g_return_val_if_fail (packet != NULL, 0);
1661 g_return_val_if_fail ((packet->type == GST_RTCP_TYPE_RTPFB ||
1662 packet->type == GST_RTCP_TYPE_PSFB), 0);
1663 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
1665 data = GST_BUFFER_DATA (packet->buffer);
1668 data += packet->offset + 4;
1669 ssrc = GST_READ_UINT32_BE (data);
1675 * gst_rtcp_packet_fb_set_sender_ssrc:
1676 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
1677 * @ssrc: a sender SSRC
1679 * Set the sender SSRC field of the RTPFB or PSFB @packet.
1684 gst_rtcp_packet_fb_set_sender_ssrc (GstRTCPPacket * packet, guint32 ssrc)
1688 g_return_if_fail (packet != NULL);
1689 g_return_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
1690 packet->type == GST_RTCP_TYPE_PSFB);
1691 g_return_if_fail (GST_IS_BUFFER (packet->buffer));
1693 data = GST_BUFFER_DATA (packet->buffer);
1696 data += packet->offset + 4;
1697 GST_WRITE_UINT32_BE (data, ssrc);
1701 * gst_rtcp_packet_fb_get_media_ssrc:
1702 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
1704 * Get the media SSRC field of the RTPFB or PSFB @packet.
1706 * Returns: the media SSRC.
1711 gst_rtcp_packet_fb_get_media_ssrc (GstRTCPPacket * packet)
1716 g_return_val_if_fail (packet != NULL, 0);
1717 g_return_val_if_fail ((packet->type == GST_RTCP_TYPE_RTPFB ||
1718 packet->type == GST_RTCP_TYPE_PSFB), 0);
1719 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
1721 data = GST_BUFFER_DATA (packet->buffer);
1723 /* skip header and sender ssrc */
1724 data += packet->offset + 8;
1725 ssrc = GST_READ_UINT32_BE (data);
1731 * gst_rtcp_packet_fb_set_media_ssrc:
1732 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
1733 * @ssrc: a media SSRC
1735 * Set the media SSRC field of the RTPFB or PSFB @packet.
1740 gst_rtcp_packet_fb_set_media_ssrc (GstRTCPPacket * packet, guint32 ssrc)
1744 g_return_if_fail (packet != NULL);
1745 g_return_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
1746 packet->type == GST_RTCP_TYPE_PSFB);
1747 g_return_if_fail (GST_IS_BUFFER (packet->buffer));
1749 data = GST_BUFFER_DATA (packet->buffer);
1751 /* skip header and sender ssrc */
1752 data += packet->offset + 8;
1753 GST_WRITE_UINT32_BE (data, ssrc);
1757 * gst_rtcp_packet_fb_get_type:
1758 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
1760 * Get the feedback message type of the FB @packet.
1762 * Returns: The feedback message type.
1767 gst_rtcp_packet_fb_get_type (GstRTCPPacket * packet)
1769 g_return_val_if_fail (packet != NULL, GST_RTCP_FB_TYPE_INVALID);
1770 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
1771 packet->type == GST_RTCP_TYPE_PSFB, GST_RTCP_FB_TYPE_INVALID);
1773 return packet->count;
1777 * gst_rtcp_packet_fb_set_type:
1778 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
1779 * @type: the #GstRTCPFBType to set
1781 * Set the feedback message type of the FB @packet.
1786 gst_rtcp_packet_fb_set_type (GstRTCPPacket * packet, GstRTCPFBType type)
1790 g_return_if_fail (packet != NULL);
1791 g_return_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
1792 packet->type == GST_RTCP_TYPE_PSFB);
1793 g_return_if_fail (GST_IS_BUFFER (packet->buffer));
1795 data = GST_BUFFER_DATA (packet->buffer);
1797 data[packet->offset] = (data[packet->offset] & 0xe0) | type;
1798 packet->count = type;
1802 * gst_rtcp_ntp_to_unix:
1803 * @ntptime: an NTP timestamp
1805 * Converts an NTP time to UNIX nanoseconds. @ntptime can typically be
1806 * the NTP time of an SR RTCP message and contains, in the upper 32 bits, the
1807 * number of seconds since 1900 and, in the lower 32 bits, the fractional
1808 * seconds. The resulting value will be the number of nanoseconds since 1970.
1810 * Returns: the UNIX time for @ntptime in nanoseconds.
1813 gst_rtcp_ntp_to_unix (guint64 ntptime)
1817 /* conversion from NTP timestamp (seconds since 1900) to seconds since
1819 unixtime = ntptime - (G_GUINT64_CONSTANT (2208988800) << 32);
1820 /* conversion to nanoseconds */
1822 gst_util_uint64_scale (unixtime, GST_SECOND,
1823 (G_GINT64_CONSTANT (1) << 32));
1829 * gst_rtcp_unix_to_ntp:
1830 * @unixtime: an UNIX timestamp in nanoseconds
1832 * Converts a UNIX timestamp in nanoseconds to an NTP time. The caller should
1833 * pass a value with nanoseconds since 1970. The NTP time will, in the upper
1834 * 32 bits, contain the number of seconds since 1900 and, in the lower 32
1835 * bits, the fractional seconds. The resulting value can be used as an ntptime
1836 * for constructing SR RTCP packets.
1838 * Returns: the NTP time for @unixtime.
1841 gst_rtcp_unix_to_ntp (guint64 unixtime)
1845 /* convert clock time to NTP time. upper 32 bits should contain the seconds
1846 * and the lower 32 bits, the fractions of a second. */
1848 gst_util_uint64_scale (unixtime, (G_GINT64_CONSTANT (1) << 32),
1850 /* conversion from UNIX timestamp (seconds since 1970) to NTP (seconds
1852 ntptime += (G_GUINT64_CONSTANT (2208988800) << 32);
1858 * gst_rtcp_sdes_type_to_name:
1859 * @type: a #GstRTCPSDESType
1861 * Converts @type to the string equivalent. The string is typically used as a
1862 * key in a #GstStructure containing SDES items.
1864 * Returns: the string equivalent of @type
1869 gst_rtcp_sdes_type_to_name (GstRTCPSDESType type)
1871 const gchar *result;
1874 case GST_RTCP_SDES_CNAME:
1877 case GST_RTCP_SDES_NAME:
1880 case GST_RTCP_SDES_EMAIL:
1883 case GST_RTCP_SDES_PHONE:
1886 case GST_RTCP_SDES_LOC:
1887 result = "location";
1889 case GST_RTCP_SDES_TOOL:
1892 case GST_RTCP_SDES_NOTE:
1895 case GST_RTCP_SDES_PRIV:
1906 * gst_rtcp_sdes_name_to_type:
1907 * @name: a SDES name
1909 * Convert @name into a @GstRTCPSDESType. @name is typically a key in a
1910 * #GstStructure containing SDES items.
1912 * Returns: the #GstRTCPSDESType for @name or #GST_RTCP_SDES_PRIV when @name
1913 * is a private sdes item.
1918 gst_rtcp_sdes_name_to_type (const gchar * name)
1920 if (name == NULL || strlen (name) == 0)
1921 return GST_RTCP_SDES_INVALID;
1923 if (strcmp ("cname", name) == 0)
1924 return GST_RTCP_SDES_CNAME;
1926 if (strcmp ("name", name) == 0)
1927 return GST_RTCP_SDES_NAME;
1929 if (strcmp ("email", name) == 0)
1930 return GST_RTCP_SDES_EMAIL;
1932 if (strcmp ("phone", name) == 0)
1933 return GST_RTCP_SDES_PHONE;
1935 if (strcmp ("location", name) == 0)
1936 return GST_RTCP_SDES_LOC;
1938 if (strcmp ("tool", name) == 0)
1939 return GST_RTCP_SDES_TOOL;
1941 if (strcmp ("note", name) == 0)
1942 return GST_RTCP_SDES_NOTE;
1944 return GST_RTCP_SDES_PRIV;
1948 * gst_rtcp_packet_fb_get_fci_length:
1949 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
1951 * Get the length of the Feedback Control Information attached to a
1952 * RTPFB or PSFB @packet.
1954 * Returns: The length of the FCI in 32-bit words.
1959 gst_rtcp_packet_fb_get_fci_length (GstRTCPPacket * packet)
1963 g_return_val_if_fail (packet != NULL, 0);
1964 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
1965 packet->type == GST_RTCP_TYPE_PSFB, 0);
1966 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
1968 data = GST_BUFFER_DATA (packet->buffer) + packet->offset + 2;
1970 return GST_READ_UINT16_BE (data) - 2;
1974 * gst_rtcp_packet_fb_set_fci_length:
1975 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
1976 * @wordlen: Length of the FCI in 32-bit words
1978 * Set the length of the Feedback Control Information attached to a
1979 * RTPFB or PSFB @packet.
1981 * Returns: %TRUE if there was enough space in the packet to add this much FCI
1986 gst_rtcp_packet_fb_set_fci_length (GstRTCPPacket * packet, guint16 wordlen)
1990 g_return_val_if_fail (packet != NULL, FALSE);
1991 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
1992 packet->type == GST_RTCP_TYPE_PSFB, FALSE);
1993 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
1995 if (GST_BUFFER_SIZE (packet->buffer) < packet->offset + ((wordlen + 3) * 4))
1998 data = GST_BUFFER_DATA (packet->buffer) + packet->offset + 2;
2000 GST_WRITE_UINT16_BE (data, wordlen);
2006 * gst_rtcp_packet_fb_get_fci:
2007 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
2009 * Get the Feedback Control Information attached to a RTPFB or PSFB @packet.
2011 * Returns: a pointer to the FCI
2016 gst_rtcp_packet_fb_get_fci (GstRTCPPacket * packet)
2020 g_return_val_if_fail (packet != NULL, NULL);
2021 g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
2022 packet->type == GST_RTCP_TYPE_PSFB, NULL);
2023 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), NULL);
2025 data = GST_BUFFER_DATA (packet->buffer) + packet->offset;
2027 if (GST_READ_UINT16_BE (data + 2) <= 2)