2 * Copyright (C) <2008> Wim Taymans <wim.taymans@gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 #include "gstrdtbuffer.h"
24 gst_rdt_buffer_validate_data (guint8 * data, guint len)
30 gst_rdt_buffer_validate (GstBuffer * buffer)
36 gst_rdt_buffer_get_packet_count (GstBuffer * buffer)
41 g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
44 if (gst_rdt_buffer_get_first_packet (buffer, &packet)) {
47 } while (gst_rdt_packet_move_to_next (&packet));
53 read_packet_header (GstRDTPacket * packet)
62 g_return_val_if_fail (packet != NULL, FALSE);
63 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
65 gst_buffer_map (packet->buffer, &map, GST_MAP_READ);
69 offset = packet->offset;
71 /* check if we are at the end of the buffer, we add 3 because we also want to
72 * ensure we can read the type, which is always at offset 1 and 2 bytes long. */
73 if (offset + 3 > size)
77 packet->type = GST_READ_UINT16_BE (&data[offset + 1]);
82 /* figure out the length of the packet, this depends on the type */
83 if (GST_RDT_IS_DATA_TYPE (packet->type)) {
84 if (data[offset] & 0x80)
85 /* length is present */
88 switch (packet->type) {
89 case GST_RDT_TYPE_ASMACTION:
90 if (data[offset] & 0x80)
93 case GST_RDT_TYPE_BWREPORT:
94 if (data[offset] & 0x80)
97 case GST_RDT_TYPE_ACK:
98 if (data[offset] & 0x80)
101 case GST_RDT_TYPE_RTTREQ:
104 case GST_RDT_TYPE_RTTRESP:
107 case GST_RDT_TYPE_CONGESTION:
110 case GST_RDT_TYPE_STREAMEND:
113 if (data[offset] & 0x80)
115 /* stream_id_expansion */
116 if ((data[offset] & 0x7c) == 0x7c)
118 /* ext_flag, FIXME, get string length */
119 if ((data[offset] & 0x1) == 0x1)
122 case GST_RDT_TYPE_REPORT:
123 if (data[offset] & 0x80)
126 case GST_RDT_TYPE_LATENCY:
127 if (data[offset] & 0x80)
130 case GST_RDT_TYPE_INFOREQ:
132 /* request_time_ms */
133 if (data[offset] & 0x2)
136 case GST_RDT_TYPE_INFORESP:
139 if (data[offset] & 0x4) {
142 if (data[offset] & 0x2) {
146 if (data[offset] & 0x1) {
147 /* buffer_info_count, FIXME read and skip */
151 case GST_RDT_TYPE_AUTOBW:
152 if (data[offset] & 0x80)
155 case GST_RDT_TYPE_INVALID:
162 /* we have a fixed length */
163 packet->length = length;
164 } else if (length_offset != -1) {
165 /* we can read the length from an offset */
166 packet->length = GST_READ_UINT16_BE (&data[length_offset]);
168 /* length is remainder of packet */
169 packet->length = size - offset;
171 gst_buffer_unmap (packet->buffer, &map);
173 /* the length should be smaller than the remaining size */
174 if (packet->length + offset > size)
182 gst_buffer_unmap (packet->buffer, &map);
187 packet->type = GST_RDT_TYPE_INVALID;
188 gst_buffer_unmap (packet->buffer, &map);
193 packet->type = GST_RDT_TYPE_INVALID;
200 gst_rdt_buffer_get_first_packet (GstBuffer * buffer, GstRDTPacket * packet)
202 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
203 g_return_val_if_fail (packet != NULL, FALSE);
206 packet->buffer = buffer;
208 packet->type = GST_RDT_TYPE_INVALID;
209 memset (&packet->map, 0, sizeof (GstMapInfo));
211 if (!read_packet_header (packet))
218 gst_rdt_packet_move_to_next (GstRDTPacket * packet)
220 g_return_val_if_fail (packet != NULL, FALSE);
221 g_return_val_if_fail (packet->type != GST_RDT_TYPE_INVALID, FALSE);
222 g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
224 /* if we have an invalid packet, it must be the last,
226 if (packet->type == GST_RDT_TYPE_INVALID)
229 /* move to next packet */
230 packet->offset += packet->length;
232 /* try to read new header */
233 if (!read_packet_header (packet))
241 packet->type = GST_RDT_TYPE_INVALID;
247 gst_rdt_packet_get_type (GstRDTPacket * packet)
249 g_return_val_if_fail (packet != NULL, GST_RDT_TYPE_INVALID);
250 g_return_val_if_fail (packet->type != GST_RDT_TYPE_INVALID,
251 GST_RDT_TYPE_INVALID);
257 gst_rdt_packet_get_length (GstRDTPacket * packet)
259 g_return_val_if_fail (packet != NULL, 0);
260 g_return_val_if_fail (packet->type != GST_RDT_TYPE_INVALID, 0);
262 return packet->length;
266 gst_rdt_packet_to_buffer (GstRDTPacket * packet)
270 g_return_val_if_fail (packet != NULL, NULL);
271 g_return_val_if_fail (packet->type != GST_RDT_TYPE_INVALID, NULL);
274 gst_buffer_copy_region (packet->buffer, GST_BUFFER_COPY_ALL,
275 packet->offset, packet->length);
276 /* timestamp applies to all packets in this buffer */
277 GST_BUFFER_TIMESTAMP (result) = GST_BUFFER_TIMESTAMP (packet->buffer);
283 gst_rdt_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2)
285 return (gint16) (seqnum2 - seqnum1);
289 gst_rdt_packet_data_get_seq (GstRDTPacket * packet)
295 g_return_val_if_fail (packet != NULL, FALSE);
296 g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), FALSE);
298 gst_buffer_map (packet->buffer, &map, GST_MAP_READ);
300 /* skip header bits */
301 header = packet->offset + 1;
304 result = GST_READ_UINT16_BE (&map.data[header]);
306 gst_buffer_unmap (packet->buffer, &map);
312 gst_rdt_packet_data_map (GstRDTPacket * packet, guint * size)
316 gboolean length_included_flag;
317 gboolean need_reliable_flag;
319 guint8 asm_rule_number;
321 g_return_val_if_fail (packet != NULL, NULL);
322 g_return_val_if_fail (packet->map.data == NULL, NULL);
323 g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), NULL);
325 gst_buffer_map (packet->buffer, &map, GST_MAP_READ);
327 header = packet->offset;
329 length_included_flag = (map.data[header] & 0x80) == 0x80;
330 need_reliable_flag = (map.data[header] & 0x40) == 0x40;
331 stream_id = (map.data[header] & 0x3e) >> 1;
333 /* skip seq_no and header bits */
336 if (length_included_flag) {
340 asm_rule_number = (map.data[header] & 0x3f);
342 /* skip timestamp and asm_rule_number */
345 if (stream_id == 0x1f) {
346 /* skip stream_id_expansion */
349 if (need_reliable_flag) {
350 /* skip total_reliable */
353 if (asm_rule_number == 63) {
354 /* skip asm_rule_number_expansion */
359 *size = packet->length - (header - packet->offset);
363 return &map.data[header];
367 gst_rdt_packet_data_unmap (GstRDTPacket * packet)
369 g_return_val_if_fail (packet != NULL, FALSE);
370 g_return_val_if_fail (packet->map.data != NULL, FALSE);
372 gst_buffer_unmap (packet->buffer, &packet->map);
373 packet->map.data = NULL;
379 gst_rdt_packet_data_get_stream_id (GstRDTPacket * packet)
384 gboolean length_included_flag;
386 g_return_val_if_fail (packet != NULL, 0);
387 g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);
389 gst_buffer_map (packet->buffer, &map, GST_MAP_READ);
391 header = packet->offset;
393 length_included_flag = (map.data[header] & 0x80) == 0x80;
394 result = (map.data[header] & 0x3e) >> 1;
396 /* skip seq_no and header bits */
399 if (length_included_flag) {
403 /* skip asm_rule_number and timestamp */
406 /* stream_id_expansion */
407 result = GST_READ_UINT16_BE (&map.data[header]);
409 gst_buffer_unmap (packet->buffer, &map);
415 gst_rdt_packet_data_get_timestamp (GstRDTPacket * packet)
419 gboolean length_included_flag;
422 g_return_val_if_fail (packet != NULL, 0);
423 g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);
425 gst_buffer_map (packet->buffer, &map, GST_MAP_READ);
427 header = packet->offset;
429 length_included_flag = (map.data[header] & 0x80) == 0x80;
431 /* skip seq_no and header bits */
434 if (length_included_flag) {
438 /* skip asm_rule_number */
442 result = GST_READ_UINT32_BE (&map.data[header]);
443 gst_buffer_unmap (packet->buffer, &map);
449 gst_rdt_packet_data_get_flags (GstRDTPacket * packet)
454 gboolean length_included_flag;
456 g_return_val_if_fail (packet != NULL, 0);
457 g_return_val_if_fail (GST_RDT_IS_DATA_TYPE (packet->type), 0);
459 gst_buffer_map (packet->buffer, &map, GST_MAP_READ);
461 header = packet->offset;
463 length_included_flag = (map.data[header] & 0x80) == 0x80;
465 /* skip seq_no and header bits */
468 if (length_included_flag) {
473 result = map.data[header];
474 gst_buffer_unmap (packet->buffer, &map);