2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) 2004,2006 Thomas Vander Stichele <thomas at apestaart dot org>
5 * dataprotocol.c: Functions implementing the GStreamer Data Protocol
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:gstdataprotocol
25 * @short_description: Serialization of caps, buffers and events.
26 * @see_also: #GstCaps, #GstEvent, #GstBuffer
28 * This helper library provides serialization of GstBuffer, GstCaps and
29 * GstEvent structures.
31 * This serialization is useful when GStreamer needs to interface with
32 * the outside world to transport data between distinct GStreamer pipelines.
33 * The connections with the outside world generally don't have mechanisms
34 * to transport properties of these structures.
36 * For example, transporting buffers across named pipes or network connections
37 * doesn't maintain the buffer size and separation.
39 * This data protocol assumes a reliable connection-oriented transport, such as
40 * TCP, a pipe, or a file. The protocol does not serialize the caps for
41 * each buffer; instead, it transport the caps only when they change in the
42 * stream. This implies that there will always be a caps packet before any
45 * The versioning of the protocol is independent of GStreamer's version.
46 * The major number gets incremented, and the minor reset, for incompatible
47 * changes. The minor number gets incremented for compatible changes that
48 * allow clients who do not completely understand the newer protocol version
49 * to still decode what they do understand.
51 * Version 0.2 serializes only a small subset of all events, with a custom
52 * payload for each type. Also, all GDP streams start with the initial caps
55 * Version 1.0 serializes all events by taking the string representation of
56 * the event as the payload. In addition, GDP streams can now start with
57 * events as well, as required by the new data stream model in GStreamer 0.10.
59 * Converting buffers, caps and events to GDP buffers is done using a
60 * #GstDPPacketizer object and invoking its packetizer functions.
61 * For backwards-compatibility reasons, the old 0.2 methods are still
62 * available but deprecated.
64 * For reference, this image shows the byte layout of the GDP header:
66 * <inlinegraphic format="PNG" fileref="gdp-header.png"></inlinegraphic>
74 #include <gst/dataprotocol/dataprotocol.h>
75 #include <glib/gprintf.h> /* g_sprintf */
76 #include <string.h> /* strlen */
77 #include "dp-private.h"
80 GST_DEBUG_CATEGORY_STATIC (data_protocol_debug);
81 #define GST_CAT_DEFAULT data_protocol_debug
85 /* write first 6 bytes of header */
86 #define GST_DP_INIT_HEADER(h, version, flags, type) \
88 gint maj = 0, min = 0; \
90 case GST_DP_VERSION_0_2: maj = 0; min = 2; break; \
91 case GST_DP_VERSION_1_0: maj = 1; min = 0; break; \
93 h[0] = (guint8) maj; \
94 h[1] = (guint8) min; \
95 h[2] = (guint8) flags; \
96 h[3] = 0; /* padding byte */ \
97 GST_WRITE_UINT16_BE (h + 4, type); \
100 #define GST_DP_SET_CRC(h, flags, payload, length); \
103 if (flags & GST_DP_HEADER_FLAG_CRC_HEADER) \
104 /* we don't crc the last four bytes since they are crc's */ \
105 crc = gst_dp_crc (h, 58); \
106 GST_WRITE_UINT16_BE (h + 58, crc); \
109 if (length && (flags & GST_DP_HEADER_FLAG_CRC_PAYLOAD)) \
110 crc = gst_dp_crc (payload, length); \
111 GST_WRITE_UINT16_BE (h + 60, crc); \
114 /* calculate a CCITT 16 bit CRC check value for a given byte array */
116 * this code snippet is adapted from a web page I found
117 * it is identical except for cleanups, and a final XOR with 0xffff
118 * as outlined in the uecp spec
120 * XMODEM x^16 + x^12 + x^5 + 1
124 #define CRC_INIT 0xFFFF
126 /*** HELPER FUNCTIONS ***/
129 gst_dp_header_from_buffer_any (const GstBuffer * buffer, GstDPHeaderFlag flags,
130 guint * length, guint8 ** header, GstDPVersion version)
137 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
138 g_return_val_if_fail (length, FALSE);
139 g_return_val_if_fail (header, FALSE);
141 *length = GST_DP_HEADER_LENGTH;
142 h = g_malloc0 (GST_DP_HEADER_LENGTH);
144 /* version, flags, type */
145 GST_DP_INIT_HEADER (h, version, flags, GST_DP_PAYLOAD_BUFFER);
147 data = gst_buffer_map ((GstBuffer *) buffer, &size, NULL, GST_MAP_READ);
149 /* buffer properties */
150 GST_WRITE_UINT32_BE (h + 6, size);
151 GST_WRITE_UINT64_BE (h + 10, GST_BUFFER_TIMESTAMP (buffer));
152 GST_WRITE_UINT64_BE (h + 18, GST_BUFFER_DURATION (buffer));
153 GST_WRITE_UINT64_BE (h + 26, GST_BUFFER_OFFSET (buffer));
154 GST_WRITE_UINT64_BE (h + 34, GST_BUFFER_OFFSET_END (buffer));
156 /* data flags; eats two bytes from the ABI area */
157 /* we copy everything but the read-only flags */
158 flags_mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_DISCONT |
159 GST_BUFFER_FLAG_IN_CAPS | GST_BUFFER_FLAG_GAP |
160 GST_BUFFER_FLAG_DELTA_UNIT;
162 GST_WRITE_UINT16_BE (h + 42, GST_BUFFER_FLAGS (buffer) & flags_mask);
164 GST_DP_SET_CRC (h, flags, data, size);
166 gst_buffer_unmap ((GstBuffer *) buffer, data, size);
168 GST_LOG ("created header from buffer:");
169 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
175 gst_dp_packet_from_caps_any (const GstCaps * caps, GstDPHeaderFlag flags,
176 guint * length, guint8 ** header, guint8 ** payload, GstDPVersion version)
180 guint payload_length;
182 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
183 g_return_val_if_fail (length, FALSE);
184 g_return_val_if_fail (header, FALSE);
185 g_return_val_if_fail (payload, FALSE);
187 *length = GST_DP_HEADER_LENGTH;
188 h = g_malloc0 (GST_DP_HEADER_LENGTH);
190 string = (guchar *) gst_caps_to_string (caps);
191 payload_length = strlen ((gchar *) string) + 1; /* include trailing 0 */
193 /* version, flags, type */
194 GST_DP_INIT_HEADER (h, version, flags, GST_DP_PAYLOAD_CAPS);
196 /* buffer properties */
197 GST_WRITE_UINT32_BE (h + 6, payload_length);
198 GST_WRITE_UINT64_BE (h + 10, (guint64) 0);
199 GST_WRITE_UINT64_BE (h + 18, (guint64) 0);
200 GST_WRITE_UINT64_BE (h + 26, (guint64) 0);
201 GST_WRITE_UINT64_BE (h + 34, (guint64) 0);
203 GST_DP_SET_CRC (h, flags, string, payload_length);
205 GST_LOG ("created header from caps:");
206 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
213 /*** PUBLIC FUNCTIONS ***/
215 static const guint16 gst_dp_crc_table[256] = {
216 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
217 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
218 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
219 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
220 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
221 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
222 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
223 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
224 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
225 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
226 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
227 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
228 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
229 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
230 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
231 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
232 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
233 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
234 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
235 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
236 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
237 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
238 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
239 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
240 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
241 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
242 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
243 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
244 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
245 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
246 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
247 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
252 * @buffer: array of bytes
253 * @length: the length of @buffer
255 * Calculate a CRC for the given buffer over the given number of bytes.
256 * This is only provided for verification purposes; typical GDP users
257 * will not need this function.
259 * Returns: a two-byte CRC checksum.
262 gst_dp_crc (const guint8 * buffer, guint length)
264 guint16 crc_register = CRC_INIT;
266 g_return_val_if_fail (buffer != NULL || length == 0, 0);
270 crc_register = (guint16) ((crc_register << 8) ^
271 gst_dp_crc_table[((crc_register >> 8) & 0x00ff) ^ *buffer++]);
273 return (0xffff ^ crc_register);
276 /* debugging function; dumps byte array values per 8 bytes */
277 /* FIXME: would be nice to merge this with gst_util_dump_mem () */
279 gst_dp_dump_byte_array (guint8 * array, guint length)
282 int n = 8; /* number of bytes per line */
283 gchar *line = g_malloc0 (3 * n + 1);
285 GST_LOG ("dumping byte array of length %d", length);
286 for (i = 0; i < length; ++i) {
287 g_sprintf (line + 3 * (i % n), "%02x ", array[i]);
288 if (i % n == (n - 1)) {
289 GST_LOG ("%03d: %s", i - (n - 1), line);
293 GST_LOG ("%03d: %s", (i / n) * n, line);
299 gst_dp_version_get_type (void)
301 static gsize gst_dp_version_type = 0;
302 static const GEnumValue gst_dp_version[] = {
303 {GST_DP_VERSION_0_2, "GST_DP_VERSION_0_2", "0.2"},
304 {GST_DP_VERSION_1_0, "GST_DP_VERSION_1_0", "1.0"},
308 if (g_once_init_enter (&gst_dp_version_type)) {
309 GType tmp = g_enum_register_static ("GstDPVersion", gst_dp_version);
310 g_once_init_leave (&gst_dp_version_type, tmp);
313 return (GType) gst_dp_version_type;
319 * Initialize GStreamer Data Protocol library.
321 * Should be called before using these functions from source linking
322 * to this source file.
327 static gboolean _gst_dp_initialized = FALSE;
329 if (_gst_dp_initialized)
332 _gst_dp_initialized = TRUE;
334 g_type_class_ref (gst_dp_version_get_type ());
336 GST_DEBUG_CATEGORY_INIT (data_protocol_debug, "gdp", 0,
337 "GStreamer Data Protocol");
341 * gst_dp_header_payload_length:
342 * @header: the byte header of the packet array
344 * Get the length of the payload described by @header.
346 * Returns: the length of the payload this header describes.
349 gst_dp_header_payload_length (const guint8 * header)
351 g_return_val_if_fail (header != NULL, 0);
353 return GST_DP_HEADER_PAYLOAD_LENGTH (header);
357 * gst_dp_header_payload_type:
358 * @header: the byte header of the packet array
360 * Get the type of the payload described by @header.
362 * Returns: the #GstDPPayloadType the payload this header describes.
365 gst_dp_header_payload_type (const guint8 * header)
367 g_return_val_if_fail (header != NULL, GST_DP_PAYLOAD_NONE);
369 return GST_DP_HEADER_PAYLOAD_TYPE (header);
372 /*** PACKETIZER FUNCTIONS ***/
375 gst_dp_header_from_buffer_1_0 (const GstBuffer * buffer, GstDPHeaderFlag flags,
376 guint * length, guint8 ** header)
378 return gst_dp_header_from_buffer_any (buffer, flags, length, header,
383 gst_dp_packet_from_caps_1_0 (const GstCaps * caps, GstDPHeaderFlag flags,
384 guint * length, guint8 ** header, guint8 ** payload)
386 return gst_dp_packet_from_caps_any (caps, flags, length, header, payload,
391 gst_dp_packet_from_event_1_0 (const GstEvent * event, GstDPHeaderFlag flags,
392 guint * length, guint8 ** header, guint8 ** payload)
395 guint32 pl_length; /* length of payload */
396 guchar *string = NULL;
397 const GstStructure *structure;
399 g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
400 g_return_val_if_fail (length, FALSE);
401 g_return_val_if_fail (header, FALSE);
402 g_return_val_if_fail (payload, FALSE);
404 *length = GST_DP_HEADER_LENGTH;
405 h = g_malloc0 (GST_DP_HEADER_LENGTH);
407 structure = gst_event_get_structure ((GstEvent *) event);
409 string = (guchar *) gst_structure_to_string (structure);
410 GST_LOG ("event %p has structure, string %s", event, string);
411 pl_length = strlen ((gchar *) string) + 1; /* include trailing 0 */
413 GST_LOG ("event %p has no structure", event);
417 /* version, flags, type */
418 GST_DP_INIT_HEADER (h, GST_DP_VERSION_1_0, flags,
419 GST_DP_PAYLOAD_EVENT_NONE + GST_EVENT_TYPE (event));
422 GST_WRITE_UINT32_BE (h + 6, pl_length);
424 GST_WRITE_UINT64_BE (h + 10, GST_EVENT_TIMESTAMP (event));
426 GST_DP_SET_CRC (h, flags, string, pl_length);
428 GST_LOG ("created header from event:");
429 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
435 /*** DEPACKETIZING FUNCTIONS ***/
438 * gst_dp_buffer_from_header:
439 * @header_length: the length of the packet header
440 * @header: the byte array of the packet header
442 * Creates a newly allocated #GstBuffer from the given header.
443 * The buffer data needs to be copied into it before validating.
445 * Use this function if you want to pre-allocate a buffer based on the
446 * packet header to read the packet payload in to.
448 * This function does not check the header passed to it, use
449 * gst_dp_validate_header() first if the header data is unchecked.
451 * Returns: A #GstBuffer if the buffer was successfully created, or NULL.
454 gst_dp_buffer_from_header (guint header_length, const guint8 * header)
458 g_return_val_if_fail (header != NULL, NULL);
459 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, NULL);
460 g_return_val_if_fail (GST_DP_HEADER_PAYLOAD_TYPE (header) ==
461 GST_DP_PAYLOAD_BUFFER, NULL);
464 gst_buffer_new_and_alloc ((guint) GST_DP_HEADER_PAYLOAD_LENGTH (header));
466 GST_BUFFER_TIMESTAMP (buffer) = GST_DP_HEADER_TIMESTAMP (header);
467 GST_BUFFER_DURATION (buffer) = GST_DP_HEADER_DURATION (header);
468 GST_BUFFER_OFFSET (buffer) = GST_DP_HEADER_OFFSET (header);
469 GST_BUFFER_OFFSET_END (buffer) = GST_DP_HEADER_OFFSET_END (header);
470 GST_BUFFER_FLAGS (buffer) = GST_DP_HEADER_BUFFER_FLAGS (header);
476 * gst_dp_caps_from_packet:
477 * @header_length: the length of the packet header
478 * @header: the byte array of the packet header
479 * @payload: the byte array of the packet payload
481 * Creates a newly allocated #GstCaps from the given packet.
483 * This function does not check the arguments passed to it, use
484 * gst_dp_validate_packet() first if the header and payload data are
487 * Returns: A #GstCaps containing the caps represented in the packet,
488 * or NULL if the packet could not be converted.
491 gst_dp_caps_from_packet (guint header_length, const guint8 * header,
492 const guint8 * payload)
497 g_return_val_if_fail (header, NULL);
498 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, NULL);
499 g_return_val_if_fail (GST_DP_HEADER_PAYLOAD_TYPE (header) ==
500 GST_DP_PAYLOAD_CAPS, NULL);
501 g_return_val_if_fail (payload, NULL);
503 /* 0 sized payload length will work create NULL string */
504 string = g_strndup ((gchar *) payload, GST_DP_HEADER_PAYLOAD_LENGTH (header));
505 caps = gst_caps_from_string (string);
512 gst_dp_event_from_packet_0_2 (guint header_length, const guint8 * header,
513 const guint8 * payload)
515 GstEvent *event = NULL;
518 type = GST_DP_HEADER_PAYLOAD_TYPE (header) - GST_DP_PAYLOAD_EVENT_NONE;
520 case GST_EVENT_UNKNOWN:
521 GST_WARNING ("Unknown event, ignoring");
524 case GST_EVENT_FLUSH_START:
525 case GST_EVENT_FLUSH_STOP:
526 case GST_EVENT_SEGMENT:
527 event = gst_event_new_custom (type, NULL);
528 GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
535 GstSeekType cur_type, stop_type;
538 g_return_val_if_fail (payload != NULL, NULL);
540 /* FIXME, read rate */
542 format = (GstFormat) GST_READ_UINT32_BE (payload);
543 flags = (GstSeekFlags) GST_READ_UINT32_BE (payload + 4);
544 cur_type = (GstSeekType) GST_READ_UINT32_BE (payload + 8);
545 cur = (gint64) GST_READ_UINT64_BE (payload + 12);
546 stop_type = (GstSeekType) GST_READ_UINT32_BE (payload + 20);
547 stop = (gint64) GST_READ_UINT64_BE (payload + 24);
549 event = gst_event_new_seek (rate, format, flags, cur_type, cur,
551 GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
555 case GST_EVENT_NAVIGATION:
557 GST_WARNING ("Unhandled event type %d, ignoring", type);
560 GST_WARNING ("Unknown event type %d, ignoring", type);
568 gst_dp_event_from_packet_1_0 (guint header_length, const guint8 * header,
569 const guint8 * payload)
571 GstEvent *event = NULL;
573 gchar *string = NULL;
574 GstStructure *s = NULL;
576 type = GST_DP_HEADER_PAYLOAD_TYPE (header) - GST_DP_PAYLOAD_EVENT_NONE;
579 g_strndup ((gchar *) payload, GST_DP_HEADER_PAYLOAD_LENGTH (header));
580 s = gst_structure_from_string (string, NULL);
583 event = gst_event_new_custom (type, s);
589 * gst_dp_event_from_packet:
590 * @header_length: the length of the packet header
591 * @header: the byte array of the packet header
592 * @payload: the byte array of the packet payload
594 * Creates a newly allocated #GstEvent from the given packet.
596 * This function does not check the arguments passed to it, use
597 * gst_dp_validate_packet() first if the header and payload data are
600 * Returns: A #GstEvent if the event was successfully created,
601 * or NULL if an event could not be read from the payload.
604 gst_dp_event_from_packet (guint header_length, const guint8 * header,
605 const guint8 * payload)
609 g_return_val_if_fail (header, NULL);
610 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, NULL);
612 major = GST_DP_HEADER_MAJOR_VERSION (header);
613 minor = GST_DP_HEADER_MINOR_VERSION (header);
615 if (major == 0 && minor == 2)
616 return gst_dp_event_from_packet_0_2 (header_length, header, payload);
617 else if (major == 1 && minor == 0)
618 return gst_dp_event_from_packet_1_0 (header_length, header, payload);
620 GST_ERROR ("Unknown GDP version %d.%d", major, minor);
626 * gst_dp_validate_header:
627 * @header_length: the length of the packet header
628 * @header: the byte array of the packet header
630 * Validates the given packet header by checking the CRC checksum.
632 * Returns: %TRUE if the CRC matches, or no CRC checksum is present.
635 gst_dp_validate_header (guint header_length, const guint8 * header)
637 guint16 crc_read, crc_calculated;
639 g_return_val_if_fail (header != NULL, FALSE);
640 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, FALSE);
642 if (!(GST_DP_HEADER_FLAGS (header) & GST_DP_HEADER_FLAG_CRC_HEADER))
645 crc_read = GST_DP_HEADER_CRC_HEADER (header);
647 /* don't include the last two crc fields for the crc check */
648 crc_calculated = gst_dp_crc (header, header_length - 4);
649 if (crc_read != crc_calculated)
652 GST_LOG ("header crc validation: %02x", crc_read);
658 GST_WARNING ("header crc mismatch: read %02x, calculated %02x", crc_read,
665 * gst_dp_validate_payload:
666 * @header_length: the length of the packet header
667 * @header: the byte array of the packet header
668 * @payload: the byte array of the packet payload
670 * Validates the given packet payload using the given packet header
671 * by checking the CRC checksum.
673 * Returns: %TRUE if the CRC matches, or no CRC checksum is present.
676 gst_dp_validate_payload (guint header_length, const guint8 * header,
677 const guint8 * payload)
679 guint16 crc_read, crc_calculated;
681 g_return_val_if_fail (header != NULL, FALSE);
682 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, FALSE);
684 if (!(GST_DP_HEADER_FLAGS (header) & GST_DP_HEADER_FLAG_CRC_PAYLOAD))
687 crc_read = GST_DP_HEADER_CRC_PAYLOAD (header);
688 crc_calculated = gst_dp_crc (payload, GST_DP_HEADER_PAYLOAD_LENGTH (header));
689 if (crc_read != crc_calculated)
692 GST_LOG ("payload crc validation: %02x", crc_read);
698 GST_WARNING ("payload crc mismatch: read %02x, calculated %02x", crc_read,
705 * gst_dp_validate_packet:
706 * @header_length: the length of the packet header
707 * @header: the byte array of the packet header
708 * @payload: the byte array of the packet payload
710 * Validates the given packet by checking version information and checksums.
712 * Returns: %TRUE if the packet validates.
715 gst_dp_validate_packet (guint header_length, const guint8 * header,
716 const guint8 * payload)
718 if (!gst_dp_validate_header (header_length, header))
720 if (!gst_dp_validate_payload (header_length, header, payload))
727 * gst_dp_packetizer_new:
728 * @version: the #GstDPVersion of the protocol to packetize for.
730 * Creates a new packetizer.
732 * Returns: a newly allocated #GstDPPacketizer
735 gst_dp_packetizer_new (GstDPVersion version)
737 GstDPPacketizer *ret;
739 ret = g_malloc0 (sizeof (GstDPPacketizer));
740 ret->version = version;
743 case GST_DP_VERSION_1_0:
744 ret->header_from_buffer = gst_dp_header_from_buffer_1_0;
745 ret->packet_from_caps = gst_dp_packet_from_caps_1_0;
746 ret->packet_from_event = gst_dp_packet_from_event_1_0;
758 * gst_dp_packetizer_free:
759 * @packetizer: the #GstDPPacketizer to free.
761 * Free the given packetizer.
764 gst_dp_packetizer_free (GstDPPacketizer * packetizer)