/** * gst_rtp_buffer_allocate_data: * @buffer: a #GstBuffer * @payload_len: the length of the payload * @pad_len: the amount of padding * @csrc_count: the number of CSRC entries * * Allocate enough data in @buffer to hold an RTP packet with @csrc_count CSRCs, * a payload length of @payload_len and padding of @pad_len. * MALLOCDATA of @buffer will be overwritten and will not be freed. * All other RTP header fields will be set to 0/FALSE. */ void gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len, guint8 pad_len, guint8 csrc_count) { guint len; guint8 *data; g_return_if_fail (csrc_count <= 15); g_return_if_fail (GST_IS_BUFFER (buffer)); len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32) + payload_len + pad_len; data = g_malloc (len); GST_BUFFER_MALLOCDATA (buffer) = data; GST_BUFFER_DATA (buffer) = data; GST_BUFFER_SIZE (buffer) = len; /* fill in defaults */ GST_RTP_HEADER_VERSION (data) = GST_RTP_VERSION; GST_RTP_HEADER_PADDING (data) = FALSE; GST_RTP_HEADER_EXTENSION (data) = FALSE; GST_RTP_HEADER_CSRC_COUNT (data) = csrc_count; memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, 0), 0, csrc_count * sizeof (guint32)); GST_RTP_HEADER_MARKER (data) = FALSE; GST_RTP_HEADER_PAYLOAD_TYPE (data) = 0; GST_RTP_HEADER_SEQ (data) = 0; GST_RTP_HEADER_TIMESTAMP (data) = 0; GST_RTP_HEADER_SSRC (data) = 0; }
static GstBufferListItem set_seq_header (GstBuffer ** buffer, guint group, guint idx, guint16 * seq) { GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (*buffer)) = g_htons (*seq); (*seq)++; return GST_BUFFER_LIST_SKIP_GROUP; }
EXPORT_C #endif void gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq) { GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)) = g_htons (seq); }
EXPORT_C #endif guint16 gst_rtp_buffer_get_seq (GstBuffer * buffer) { return g_ntohs (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer))); }
/** * gst_rtp_buffer_list_get_seq: * @list: the buffer list * * Get the sequence number of the first RTP packet in @list. * All packets within @list have the same sequence number. * * Returns: The seq number * * Since: 0.10.24 */ guint16 gst_rtp_buffer_list_get_seq (GstBufferList * list) { GstBuffer *buffer; buffer = gst_buffer_list_get (list, 0, 0); g_return_val_if_fail (buffer != NULL, 0); return g_ntohl (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer))); }
EXPORT_C #endif void gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq) { g_return_if_fail (GST_IS_BUFFER (buffer)); g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL); GST_RTP_HEADER_SEQ (buffer) = g_htons (seq); }
EXPORT_C #endif guint16 gst_rtp_buffer_get_seq (GstBuffer * buffer) { g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0); return g_ntohs (GST_RTP_HEADER_SEQ (buffer)); }
/** * gst_rtp_buffer_list_validate: * @list: the buffer list to validate * * Check if all RTP packets in the @list are valid using validate_data(). * Use this function to validate an list before using the other functions in * this module. * * Returns: TRUE if @list consists only of valid RTP packets. * * Since: 0.10.24 */ gboolean gst_rtp_buffer_list_validate (GstBufferList * list) { guint16 prev_seqnum = 0; GstBufferListIterator *it; guint i = 0; g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE); it = gst_buffer_list_iterate (list); g_return_val_if_fail (it != NULL, FALSE); /* iterate through all the RTP packets in the list */ while (gst_buffer_list_iterator_next_group (it)) { GstBuffer *rtpbuf; GstBuffer *paybuf; guint8 *packet_header; guint8 *packet_payload; guint payload_size; guint packet_size; /* each group should consists of 2 buffers: one containing the RTP header * and the other one the payload, FIXME, relax the requirement of only one * payload buffer. */ if (gst_buffer_list_iterator_n_buffers (it) != 2) goto invalid_list; /* get the RTP header */ rtpbuf = gst_buffer_list_iterator_next (it); packet_header = GST_BUFFER_DATA (rtpbuf); if (packet_header == NULL) goto invalid_list; /* get the payload */ paybuf = gst_buffer_list_iterator_next (it); packet_payload = GST_BUFFER_DATA (paybuf); if (packet_payload == NULL) { goto invalid_list; } payload_size = GST_BUFFER_SIZE (paybuf); if (payload_size == 0) { goto invalid_list; } /* the size of the RTP packet within the current group */ packet_size = GST_BUFFER_SIZE (rtpbuf) + payload_size; /* check the sequence number */ if (G_UNLIKELY (i == 0)) { prev_seqnum = g_ntohs (GST_RTP_HEADER_SEQ (packet_header)); i++; } else { if (++prev_seqnum != g_ntohs (GST_RTP_HEADER_SEQ (packet_header))) goto invalid_list; } /* validate packet */ if (!validate_data (packet_header, packet_size, packet_payload, payload_size)) { goto invalid_list; } } gst_buffer_list_iterator_free (it); return TRUE; /* ERRORS */ invalid_list: { gst_buffer_list_iterator_free (it); return FALSE; } }