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)
135 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
136 g_return_val_if_fail (length, FALSE);
137 g_return_val_if_fail (header, FALSE);
139 *length = GST_DP_HEADER_LENGTH;
140 h = g_malloc0 (GST_DP_HEADER_LENGTH);
142 /* version, flags, type */
143 GST_DP_INIT_HEADER (h, version, flags, GST_DP_PAYLOAD_BUFFER);
145 /* buffer properties */
146 GST_WRITE_UINT32_BE (h + 6, GST_BUFFER_SIZE (buffer));
147 GST_WRITE_UINT64_BE (h + 10, GST_BUFFER_TIMESTAMP (buffer));
148 GST_WRITE_UINT64_BE (h + 18, GST_BUFFER_DURATION (buffer));
149 GST_WRITE_UINT64_BE (h + 26, GST_BUFFER_OFFSET (buffer));
150 GST_WRITE_UINT64_BE (h + 34, GST_BUFFER_OFFSET_END (buffer));
152 /* data flags; eats two bytes from the ABI area */
153 /* we copy everything but the read-only flags */
154 flags_mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_DISCONT |
155 GST_BUFFER_FLAG_IN_CAPS | GST_BUFFER_FLAG_GAP |
156 GST_BUFFER_FLAG_DELTA_UNIT;
158 GST_WRITE_UINT16_BE (h + 42, GST_BUFFER_FLAGS (buffer) & flags_mask);
160 GST_DP_SET_CRC (h, flags, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
162 GST_LOG ("created header from buffer:");
163 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
169 gst_dp_packet_from_caps_any (const GstCaps * caps, GstDPHeaderFlag flags,
170 guint * length, guint8 ** header, guint8 ** payload, GstDPVersion version)
174 guint payload_length;
176 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
177 g_return_val_if_fail (length, FALSE);
178 g_return_val_if_fail (header, FALSE);
179 g_return_val_if_fail (payload, FALSE);
181 *length = GST_DP_HEADER_LENGTH;
182 h = g_malloc0 (GST_DP_HEADER_LENGTH);
184 string = (guchar *) gst_caps_to_string (caps);
185 payload_length = strlen ((gchar *) string) + 1; /* include trailing 0 */
187 /* version, flags, type */
188 GST_DP_INIT_HEADER (h, version, flags, GST_DP_PAYLOAD_CAPS);
190 /* buffer properties */
191 GST_WRITE_UINT32_BE (h + 6, payload_length);
192 GST_WRITE_UINT64_BE (h + 10, (guint64) 0);
193 GST_WRITE_UINT64_BE (h + 18, (guint64) 0);
194 GST_WRITE_UINT64_BE (h + 26, (guint64) 0);
195 GST_WRITE_UINT64_BE (h + 34, (guint64) 0);
197 GST_DP_SET_CRC (h, flags, string, payload_length);
199 GST_LOG ("created header from caps:");
200 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
207 /*** PUBLIC FUNCTIONS ***/
209 static const guint16 gst_dp_crc_table[256] = {
210 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
211 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
212 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
213 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
214 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
215 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
216 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
217 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
218 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
219 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
220 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
221 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
222 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
223 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
224 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
225 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
226 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
227 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
228 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
229 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
230 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
231 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
232 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
233 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
234 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
235 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
236 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
237 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
238 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
239 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
240 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
241 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
246 * @buffer: array of bytes
247 * @length: the length of @buffer
249 * Calculate a CRC for the given buffer over the given number of bytes.
250 * This is only provided for verification purposes; typical GDP users
251 * will not need this function.
253 * Returns: a two-byte CRC checksum.
256 gst_dp_crc (const guint8 * buffer, guint length)
258 guint16 crc_register = CRC_INIT;
260 g_return_val_if_fail (buffer != NULL || length == 0, 0);
264 crc_register = (guint16) ((crc_register << 8) ^
265 gst_dp_crc_table[((crc_register >> 8) & 0x00ff) ^ *buffer++]);
267 return (0xffff ^ crc_register);
270 /* debugging function; dumps byte array values per 8 bytes */
271 /* FIXME: would be nice to merge this with gst_util_dump_mem () */
273 gst_dp_dump_byte_array (guint8 * array, guint length)
276 int n = 8; /* number of bytes per line */
277 gchar *line = g_malloc0 (3 * n + 1);
279 GST_LOG ("dumping byte array of length %d", length);
280 for (i = 0; i < length; ++i) {
281 g_sprintf (line + 3 * (i % n), "%02x ", array[i]);
282 if (i % n == (n - 1)) {
283 GST_LOG ("%03d: %s", i - (n - 1), line);
287 GST_LOG ("%03d: %s", (i / n) * n, line);
293 gst_dp_version_get_type (void)
295 static gsize gst_dp_version_type = 0;
296 static const GEnumValue gst_dp_version[] = {
297 {GST_DP_VERSION_0_2, "GST_DP_VERSION_0_2", "0.2"},
298 {GST_DP_VERSION_1_0, "GST_DP_VERSION_1_0", "1.0"},
302 if (g_once_init_enter (&gst_dp_version_type)) {
303 GType tmp = g_enum_register_static ("GstDPVersion", gst_dp_version);
304 g_once_init_leave (&gst_dp_version_type, tmp);
307 return (GType) gst_dp_version_type;
313 * Initialize GStreamer Data Protocol library.
315 * Should be called before using these functions from source linking
316 * to this source file.
321 static gboolean _gst_dp_initialized = FALSE;
323 if (_gst_dp_initialized)
326 _gst_dp_initialized = TRUE;
328 g_type_class_ref (gst_dp_version_get_type ());
330 GST_DEBUG_CATEGORY_INIT (data_protocol_debug, "gdp", 0,
331 "GStreamer Data Protocol");
335 * gst_dp_header_payload_length:
336 * @header: the byte header of the packet array
338 * Get the length of the payload described by @header.
340 * Returns: the length of the payload this header describes.
343 gst_dp_header_payload_length (const guint8 * header)
345 g_return_val_if_fail (header != NULL, 0);
347 return GST_DP_HEADER_PAYLOAD_LENGTH (header);
351 * gst_dp_header_payload_type:
352 * @header: the byte header of the packet array
354 * Get the type of the payload described by @header.
356 * Returns: the #GstDPPayloadType the payload this header describes.
359 gst_dp_header_payload_type (const guint8 * header)
361 g_return_val_if_fail (header != NULL, GST_DP_PAYLOAD_NONE);
363 return GST_DP_HEADER_PAYLOAD_TYPE (header);
366 /*** PACKETIZER FUNCTIONS ***/
369 gst_dp_header_from_buffer_1_0 (const GstBuffer * buffer, GstDPHeaderFlag flags,
370 guint * length, guint8 ** header)
372 return gst_dp_header_from_buffer_any (buffer, flags, length, header,
377 gst_dp_packet_from_caps_1_0 (const GstCaps * caps, GstDPHeaderFlag flags,
378 guint * length, guint8 ** header, guint8 ** payload)
380 return gst_dp_packet_from_caps_any (caps, flags, length, header, payload,
385 gst_dp_packet_from_event_1_0 (const GstEvent * event, GstDPHeaderFlag flags,
386 guint * length, guint8 ** header, guint8 ** payload)
389 guint32 pl_length; /* length of payload */
390 guchar *string = NULL;
392 g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
393 g_return_val_if_fail (length, FALSE);
394 g_return_val_if_fail (header, FALSE);
395 g_return_val_if_fail (payload, FALSE);
397 *length = GST_DP_HEADER_LENGTH;
398 h = g_malloc0 (GST_DP_HEADER_LENGTH);
400 if (event->structure) {
401 string = (guchar *) gst_structure_to_string (event->structure);
402 GST_LOG ("event %p has structure, string %s", event, string);
403 pl_length = strlen ((gchar *) string) + 1; /* include trailing 0 */
405 GST_LOG ("event %p has no structure", event);
409 /* version, flags, type */
410 GST_DP_INIT_HEADER (h, GST_DP_VERSION_1_0, flags,
411 GST_DP_PAYLOAD_EVENT_NONE + GST_EVENT_TYPE (event));
414 GST_WRITE_UINT32_BE (h + 6, pl_length);
416 GST_WRITE_UINT64_BE (h + 10, GST_EVENT_TIMESTAMP (event));
418 GST_DP_SET_CRC (h, flags, string, pl_length);
420 GST_LOG ("created header from event:");
421 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
427 /*** DEPACKETIZING FUNCTIONS ***/
430 * gst_dp_buffer_from_header:
431 * @header_length: the length of the packet header
432 * @header: the byte array of the packet header
434 * Creates a newly allocated #GstBuffer from the given header.
435 * The buffer data needs to be copied into it before validating.
437 * Use this function if you want to pre-allocate a buffer based on the
438 * packet header to read the packet payload in to.
440 * This function does not check the header passed to it, use
441 * gst_dp_validate_header() first if the header data is unchecked.
443 * Returns: A #GstBuffer if the buffer was successfully created, or NULL.
446 gst_dp_buffer_from_header (guint header_length, const guint8 * header)
450 g_return_val_if_fail (header != NULL, NULL);
451 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, NULL);
452 g_return_val_if_fail (GST_DP_HEADER_PAYLOAD_TYPE (header) ==
453 GST_DP_PAYLOAD_BUFFER, NULL);
456 gst_buffer_new_and_alloc ((guint) GST_DP_HEADER_PAYLOAD_LENGTH (header));
458 GST_BUFFER_TIMESTAMP (buffer) = GST_DP_HEADER_TIMESTAMP (header);
459 GST_BUFFER_DURATION (buffer) = GST_DP_HEADER_DURATION (header);
460 GST_BUFFER_OFFSET (buffer) = GST_DP_HEADER_OFFSET (header);
461 GST_BUFFER_OFFSET_END (buffer) = GST_DP_HEADER_OFFSET_END (header);
462 GST_BUFFER_FLAGS (buffer) = GST_DP_HEADER_BUFFER_FLAGS (header);
468 * gst_dp_caps_from_packet:
469 * @header_length: the length of the packet header
470 * @header: the byte array of the packet header
471 * @payload: the byte array of the packet payload
473 * Creates a newly allocated #GstCaps from the given packet.
475 * This function does not check the arguments passed to it, use
476 * gst_dp_validate_packet() first if the header and payload data are
479 * Returns: A #GstCaps containing the caps represented in the packet,
480 * or NULL if the packet could not be converted.
483 gst_dp_caps_from_packet (guint header_length, const guint8 * header,
484 const guint8 * payload)
489 g_return_val_if_fail (header, NULL);
490 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, NULL);
491 g_return_val_if_fail (GST_DP_HEADER_PAYLOAD_TYPE (header) ==
492 GST_DP_PAYLOAD_CAPS, NULL);
493 g_return_val_if_fail (payload, NULL);
495 /* 0 sized payload length will work create NULL string */
496 string = g_strndup ((gchar *) payload, GST_DP_HEADER_PAYLOAD_LENGTH (header));
497 caps = gst_caps_from_string (string);
504 gst_dp_event_from_packet_0_2 (guint header_length, const guint8 * header,
505 const guint8 * payload)
507 GstEvent *event = NULL;
510 type = GST_DP_HEADER_PAYLOAD_TYPE (header) - GST_DP_PAYLOAD_EVENT_NONE;
512 case GST_EVENT_UNKNOWN:
513 GST_WARNING ("Unknown event, ignoring");
516 case GST_EVENT_FLUSH_START:
517 case GST_EVENT_FLUSH_STOP:
518 case GST_EVENT_NEWSEGMENT:
519 event = gst_event_new_custom (type, NULL);
520 GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
527 GstSeekType cur_type, stop_type;
530 g_return_val_if_fail (payload != NULL, NULL);
532 /* FIXME, read rate */
534 format = (GstFormat) GST_READ_UINT32_BE (payload);
535 flags = (GstSeekFlags) GST_READ_UINT32_BE (payload + 4);
536 cur_type = (GstSeekType) GST_READ_UINT32_BE (payload + 8);
537 cur = (gint64) GST_READ_UINT64_BE (payload + 12);
538 stop_type = (GstSeekType) GST_READ_UINT32_BE (payload + 20);
539 stop = (gint64) GST_READ_UINT64_BE (payload + 24);
541 event = gst_event_new_seek (rate, format, flags, cur_type, cur,
543 GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
547 case GST_EVENT_NAVIGATION:
549 GST_WARNING ("Unhandled event type %d, ignoring", type);
552 GST_WARNING ("Unknown event type %d, ignoring", type);
560 gst_dp_event_from_packet_1_0 (guint header_length, const guint8 * header,
561 const guint8 * payload)
563 GstEvent *event = NULL;
565 gchar *string = NULL;
566 GstStructure *s = NULL;
568 type = GST_DP_HEADER_PAYLOAD_TYPE (header) - GST_DP_PAYLOAD_EVENT_NONE;
571 g_strndup ((gchar *) payload, GST_DP_HEADER_PAYLOAD_LENGTH (header));
572 s = gst_structure_from_string (string, NULL);
575 event = gst_event_new_custom (type, s);
581 * gst_dp_event_from_packet:
582 * @header_length: the length of the packet header
583 * @header: the byte array of the packet header
584 * @payload: the byte array of the packet payload
586 * Creates a newly allocated #GstEvent from the given packet.
588 * This function does not check the arguments passed to it, use
589 * gst_dp_validate_packet() first if the header and payload data are
592 * Returns: A #GstEvent if the event was successfully created,
593 * or NULL if an event could not be read from the payload.
596 gst_dp_event_from_packet (guint header_length, const guint8 * header,
597 const guint8 * payload)
601 g_return_val_if_fail (header, NULL);
602 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, NULL);
604 major = GST_DP_HEADER_MAJOR_VERSION (header);
605 minor = GST_DP_HEADER_MINOR_VERSION (header);
607 if (major == 0 && minor == 2)
608 return gst_dp_event_from_packet_0_2 (header_length, header, payload);
609 else if (major == 1 && minor == 0)
610 return gst_dp_event_from_packet_1_0 (header_length, header, payload);
612 GST_ERROR ("Unknown GDP version %d.%d", major, minor);
618 * gst_dp_validate_header:
619 * @header_length: the length of the packet header
620 * @header: the byte array of the packet header
622 * Validates the given packet header by checking the CRC checksum.
624 * Returns: %TRUE if the CRC matches, or no CRC checksum is present.
627 gst_dp_validate_header (guint header_length, const guint8 * header)
629 guint16 crc_read, crc_calculated;
631 g_return_val_if_fail (header != NULL, FALSE);
632 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, FALSE);
634 if (!(GST_DP_HEADER_FLAGS (header) & GST_DP_HEADER_FLAG_CRC_HEADER))
637 crc_read = GST_DP_HEADER_CRC_HEADER (header);
639 /* don't include the last two crc fields for the crc check */
640 crc_calculated = gst_dp_crc (header, header_length - 4);
641 if (crc_read != crc_calculated)
644 GST_LOG ("header crc validation: %02x", crc_read);
650 GST_WARNING ("header crc mismatch: read %02x, calculated %02x", crc_read,
657 * gst_dp_validate_payload:
658 * @header_length: the length of the packet header
659 * @header: the byte array of the packet header
660 * @payload: the byte array of the packet payload
662 * Validates the given packet payload using the given packet header
663 * by checking the CRC checksum.
665 * Returns: %TRUE if the CRC matches, or no CRC checksum is present.
668 gst_dp_validate_payload (guint header_length, const guint8 * header,
669 const guint8 * payload)
671 guint16 crc_read, crc_calculated;
673 g_return_val_if_fail (header != NULL, FALSE);
674 g_return_val_if_fail (header_length >= GST_DP_HEADER_LENGTH, FALSE);
676 if (!(GST_DP_HEADER_FLAGS (header) & GST_DP_HEADER_FLAG_CRC_PAYLOAD))
679 crc_read = GST_DP_HEADER_CRC_PAYLOAD (header);
680 crc_calculated = gst_dp_crc (payload, GST_DP_HEADER_PAYLOAD_LENGTH (header));
681 if (crc_read != crc_calculated)
684 GST_LOG ("payload crc validation: %02x", crc_read);
690 GST_WARNING ("payload crc mismatch: read %02x, calculated %02x", crc_read,
697 * gst_dp_validate_packet:
698 * @header_length: the length of the packet header
699 * @header: the byte array of the packet header
700 * @payload: the byte array of the packet payload
702 * Validates the given packet by checking version information and checksums.
704 * Returns: %TRUE if the packet validates.
707 gst_dp_validate_packet (guint header_length, const guint8 * header,
708 const guint8 * payload)
710 if (!gst_dp_validate_header (header_length, header))
712 if (!gst_dp_validate_payload (header_length, header, payload))
719 * gst_dp_packetizer_new:
720 * @version: the #GstDPVersion of the protocol to packetize for.
722 * Creates a new packetizer.
724 * Returns: a newly allocated #GstDPPacketizer
727 gst_dp_packetizer_new (GstDPVersion version)
729 GstDPPacketizer *ret;
731 ret = g_malloc0 (sizeof (GstDPPacketizer));
732 ret->version = version;
735 case GST_DP_VERSION_1_0:
736 ret->header_from_buffer = gst_dp_header_from_buffer_1_0;
737 ret->packet_from_caps = gst_dp_packet_from_caps_1_0;
738 ret->packet_from_event = gst_dp_packet_from_event_1_0;
750 * gst_dp_packetizer_free:
751 * @packetizer: the #GstDPPacketizer to free.
753 * Free the given packetizer.
756 gst_dp_packetizer_free (GstDPPacketizer * packetizer)