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 (data_protocol_debug);
81 #define GST_CAT_DEFAULT data_protocol_debug
85 /* write first 6 bytes of header, as well as ABI padding */
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); \
99 GST_WRITE_UINT64_BE (h + 42, (guint64) 0); /* ABI padding */ \
100 GST_WRITE_UINT64_BE (h + 50, (guint64) 0); /* ABI padding */ \
103 #define GST_DP_SET_CRC(h, flags, payload, length); \
106 if (flags & GST_DP_HEADER_FLAG_CRC_HEADER) \
107 /* we don't crc the last four bytes since they are crc's */ \
108 crc = gst_dp_crc (h, 58); \
109 GST_WRITE_UINT16_BE (h + 58, crc); \
112 if (length && (flags & GST_DP_HEADER_FLAG_CRC_PAYLOAD)) \
113 crc = gst_dp_crc (payload, length); \
114 GST_WRITE_UINT16_BE (h + 60, crc); \
117 /* calculate a CCITT 16 bit CRC check value for a given byte array */
119 * this code snippet is adapted from a web page I found
120 * it is identical except for cleanups, and a final XOR with 0xffff
121 * as outlined in the uecp spec
123 * XMODEM x^16 + x^12 + x^5 + 1
127 #define CRC_INIT 0xFFFF
129 /*** HELPER FUNCTIONS ***/
132 gst_dp_header_from_buffer_any (const GstBuffer * buffer, GstDPHeaderFlag flags,
133 guint * length, guint8 ** header, GstDPVersion version)
138 g_return_val_if_fail (GST_IS_BUFFER (buffer), 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 /* buffer properties */
148 GST_WRITE_UINT32_BE (h + 6, GST_BUFFER_SIZE (buffer));
149 GST_WRITE_UINT64_BE (h + 10, GST_BUFFER_TIMESTAMP (buffer));
150 GST_WRITE_UINT64_BE (h + 18, GST_BUFFER_DURATION (buffer));
151 GST_WRITE_UINT64_BE (h + 26, GST_BUFFER_OFFSET (buffer));
152 GST_WRITE_UINT64_BE (h + 34, GST_BUFFER_OFFSET_END (buffer));
154 /* data flags; eats two bytes from the ABI area */
155 /* we copy everything but the read-only flags */
156 flags_mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_DISCONT |
157 GST_BUFFER_FLAG_IN_CAPS | GST_BUFFER_FLAG_GAP |
158 GST_BUFFER_FLAG_DELTA_UNIT;
160 GST_WRITE_UINT16_BE (h + 42, GST_BUFFER_FLAGS (buffer) & flags_mask);
162 GST_DP_SET_CRC (h, flags, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
164 GST_LOG ("created header from buffer:");
165 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
171 gst_dp_packet_from_caps_any (const GstCaps * caps, GstDPHeaderFlag flags,
172 guint * length, guint8 ** header, guint8 ** payload, GstDPVersion version)
176 guint payload_length;
178 /* FIXME: GST_IS_CAPS doesn't work
179 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE); */
180 g_return_val_if_fail (caps, FALSE);
181 g_return_val_if_fail (header, FALSE);
182 g_return_val_if_fail (payload, FALSE);
184 *length = GST_DP_HEADER_LENGTH;
185 h = g_malloc0 (GST_DP_HEADER_LENGTH);
187 string = (guchar *) gst_caps_to_string (caps);
188 payload_length = strlen ((gchar *) string) + 1; /* include trailing 0 */
190 /* version, flags, type */
191 GST_DP_INIT_HEADER (h, version, flags, GST_DP_PAYLOAD_CAPS);
193 /* buffer properties */
194 GST_WRITE_UINT32_BE (h + 6, payload_length);
195 GST_WRITE_UINT64_BE (h + 10, (guint64) 0);
196 GST_WRITE_UINT64_BE (h + 18, (guint64) 0);
197 GST_WRITE_UINT64_BE (h + 26, (guint64) 0);
198 GST_WRITE_UINT64_BE (h + 34, (guint64) 0);
200 GST_DP_SET_CRC (h, flags, string, payload_length);
202 GST_LOG ("created header from caps:");
203 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
210 /*** PUBLIC FUNCTIONS ***/
215 * Calculate a CRC for the given buffer over the given number of bytes.
216 * This is only provided for verification purposes; typical GDP users
217 * will not need this function.
219 * Returns: a two-byte CRC checksum.
222 gst_dp_crc (const guint8 * buffer, guint length)
224 static gboolean initialized = FALSE;
225 static guint16 crc_table[256];
226 guint16 crc_register = CRC_INIT;
227 unsigned long i, j, k;
230 for (i = 0; i < 256; i++) {
233 j = j & 0x8000 ? (j << 1) ^ POLY : j << 1;
236 crc_table[i] = (guint16) j;
243 crc_register = (guint16) ((crc_register << 8) ^
244 crc_table[((crc_register >> 8) & 0x00ff) ^ *buffer++]);
246 return (0xffff ^ crc_register);
249 /* debugging function; dumps byte array values per 8 bytes */
250 /* FIXME: would be nice to merge this with gst_util_dump_mem () */
252 gst_dp_dump_byte_array (guint8 * array, guint length)
255 int n = 8; /* number of bytes per line */
256 gchar *line = g_malloc0 (3 * n + 1);
258 GST_LOG ("dumping byte array of length %d", length);
259 for (i = 0; i < length; ++i) {
260 g_sprintf (line + 3 * (i % n), "%02x ", array[i]);
261 if (i % n == (n - 1)) {
262 GST_LOG ("%03d: %s", i - (n - 1), line);
266 GST_LOG ("%03d: %s", (i / n) * n, line);
272 gst_dp_version_get_type (void)
274 static GType gst_dp_version_type = 0;
275 static const GEnumValue gst_dp_version[] = {
276 {GST_DP_VERSION_0_2, "GDP Version 0.2", "0.2"},
277 {GST_DP_VERSION_1_0, "GDP Version 1.0", "1.0"},
281 if (!gst_dp_version_type) {
282 gst_dp_version_type =
283 g_enum_register_static ("GstDPVersion", gst_dp_version);
285 return gst_dp_version_type;
291 * Initialize GStreamer Data Protocol library.
293 * Should be called before using these functions from source linking
294 * to this source file.
299 static gboolean _gst_dp_initialized = FALSE;
301 if (_gst_dp_initialized)
304 _gst_dp_initialized = TRUE;
306 gst_dp_version_get_type ();
308 GST_DEBUG_CATEGORY_INIT (data_protocol_debug, "gdp", 0,
309 "GStreamer Data Protocol");
313 * gst_dp_header_payload_length:
314 * @header: the byte header of the packet array
316 * Get the length of the payload described by @header.
318 * Returns: the length of the payload this header describes.
321 gst_dp_header_payload_length (const guint8 * header)
323 return GST_DP_HEADER_PAYLOAD_LENGTH (header);
327 * gst_dp_header_payload_type:
328 * @header: the byte header of the packet array
330 * Get the type of the payload described by @header.
332 * Returns: the #GstDPPayloadType the payload this header describes.
335 gst_dp_header_payload_type (const guint8 * header)
337 return GST_DP_HEADER_PAYLOAD_TYPE (header);
340 /*** PACKETIZER FUNCTIONS ***/
343 * gst_dp_header_from_buffer:
344 * @buffer: a #GstBuffer to create a header for
345 * @flags: the #GDPHeaderFlags to create the header with
346 * @length: a guint pointer to store the header length in
347 * @header: a guint8 * pointer to store a newly allocated header byte array in
349 * Creates a GDP header from the given buffer.
351 * Deprecated: use a #GstDPPacketizer
353 * Returns: %TRUE if the header was successfully created.
356 gst_dp_header_from_buffer (const GstBuffer * buffer, GstDPHeaderFlag flags,
357 guint * length, guint8 ** header)
359 return gst_dp_header_from_buffer_any (buffer, flags, length, header,
364 gst_dp_header_from_buffer_1_0 (const GstBuffer * buffer, GstDPHeaderFlag flags,
365 guint * length, guint8 ** header)
367 return gst_dp_header_from_buffer_any (buffer, flags, length, header,
372 * gst_dp_packet_from_caps:
373 * @caps: a #GstCaps to create a packet for
374 * @flags: the #GDPHeaderFlags to create the header with
375 * @length: a guint pointer to store the header length in
376 * @header: a guint8 pointer to store a newly allocated header byte array in
377 * @payload: a guint8 pointer to store a newly allocated payload byte array in
379 * Creates a GDP packet from the given caps.
381 * Deprecated: use a #GstDPPacketizer
383 * Returns: %TRUE if the packet was successfully created.
386 gst_dp_packet_from_caps (const GstCaps * caps, GstDPHeaderFlag flags,
387 guint * length, guint8 ** header, guint8 ** payload)
389 return gst_dp_packet_from_caps_any (caps, flags, length, header, payload,
394 gst_dp_packet_from_caps_1_0 (const GstCaps * caps, GstDPHeaderFlag flags,
395 guint * length, guint8 ** header, guint8 ** payload)
397 return gst_dp_packet_from_caps_any (caps, flags, length, header, payload,
402 * gst_dp_packet_from_event:
403 * @event: a #GstEvent to create a packet for
404 * @flags: the #GDPHeaderFlags to create the header with
405 * @length: a guint pointer to store the header length in
406 * @header: a guint8 pointer to store a newly allocated header byte array in
407 * @payload: a guint8 pointer to store a newly allocated payload byte array in
409 * Creates a GDP packet from the given event.
411 * Deprecated: use a #GstDPPacketizer
413 * Returns: %TRUE if the packet was successfully created.
416 gst_dp_packet_from_event (const GstEvent * event, GstDPHeaderFlag flags,
417 guint * length, guint8 ** header, guint8 ** payload)
420 guint pl_length; /* length of payload */
422 g_return_val_if_fail (event, FALSE);
423 g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
424 g_return_val_if_fail (header, FALSE);
425 g_return_val_if_fail (payload, FALSE);
427 *length = GST_DP_HEADER_LENGTH;
428 h = g_malloc0 (GST_DP_HEADER_LENGTH);
430 /* first construct payload, since we need the length */
431 switch (GST_EVENT_TYPE (event)) {
432 case GST_EVENT_UNKNOWN:
433 GST_WARNING ("Unknown event, ignoring");
438 case GST_EVENT_FLUSH_START:
439 case GST_EVENT_FLUSH_STOP:
440 case GST_EVENT_NEWSEGMENT:
449 GstSeekType cur_type, stop_type;
452 gst_event_parse_seek ((GstEvent *) event, &rate, &format, &flags,
453 &cur_type, &cur, &stop_type, &stop);
455 pl_length = 4 + 4 + 4 + 8 + 4 + 8;
456 *payload = g_malloc0 (pl_length);
457 /* FIXME write rate */
458 GST_WRITE_UINT32_BE (*payload, (guint32) format);
459 GST_WRITE_UINT32_BE (*payload + 4, (guint32) flags);
460 GST_WRITE_UINT32_BE (*payload + 8, (guint32) cur_type);
461 GST_WRITE_UINT64_BE (*payload + 12, (guint64) cur);
462 GST_WRITE_UINT32_BE (*payload + 20, (guint32) stop_type);
463 GST_WRITE_UINT64_BE (*payload + 24, (guint64) stop);
467 case GST_EVENT_NAVIGATION:
469 GST_WARNING ("Unhandled event type %d, ignoring", GST_EVENT_TYPE (event));
474 GST_WARNING ("Unknown event type %d, ignoring", GST_EVENT_TYPE (event));
480 /* version, flags, type */
481 GST_DP_INIT_HEADER (h, GST_DP_VERSION_0_2, flags,
482 GST_DP_PAYLOAD_EVENT_NONE + GST_EVENT_TYPE (event));
485 GST_WRITE_UINT32_BE (h + 6, (guint32) pl_length);
487 GST_WRITE_UINT64_BE (h + 10, GST_EVENT_TIMESTAMP (event));
489 GST_DP_SET_CRC (h, flags, *payload, pl_length);
491 GST_LOG ("created header from event:");
492 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
498 gst_dp_packet_from_event_1_0 (const GstEvent * event, GstDPHeaderFlag flags,
499 guint * length, guint8 ** header, guint8 ** payload)
502 guint32 pl_length; /* length of payload */
503 guchar *string = NULL;
505 g_return_val_if_fail (event, FALSE);
506 g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
507 g_return_val_if_fail (header, FALSE);
508 g_return_val_if_fail (payload, FALSE);
510 *length = GST_DP_HEADER_LENGTH;
511 h = g_malloc0 (GST_DP_HEADER_LENGTH);
513 if (event->structure) {
514 string = (guchar *) gst_structure_to_string (event->structure);
515 GST_LOG ("event %p has structure, string %s", event, string);
516 pl_length = strlen ((gchar *) string) + 1; /* include trailing 0 */
518 GST_LOG ("event %p has no structure");
522 /* version, flags, type */
523 GST_DP_INIT_HEADER (h, GST_DP_VERSION_1_0, flags,
524 GST_DP_PAYLOAD_EVENT_NONE + GST_EVENT_TYPE (event));
527 GST_WRITE_UINT32_BE (h + 6, pl_length);
529 GST_WRITE_UINT64_BE (h + 10, GST_EVENT_TIMESTAMP (event));
531 GST_DP_SET_CRC (h, flags, *payload, pl_length);
533 GST_LOG ("created header from event:");
534 gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
540 /*** DEPACKETIZING FUNCTIONS ***/
543 * gst_dp_buffer_from_header:
544 * @header_length: the length of the packet header
545 * @header: the byte array of the packet header
547 * Creates a newly allocated #GstBuffer from the given header.
548 * The buffer data needs to be copied into it before validating.
550 * Use this function if you want to pre-allocate a buffer based on the
551 * packet header to read the packet payload in to.
553 * Returns: A #GstBuffer if the buffer was successfully created, or NULL.
556 gst_dp_buffer_from_header (guint header_length, const guint8 * header)
560 g_return_val_if_fail (GST_DP_HEADER_PAYLOAD_TYPE (header) ==
561 GST_DP_PAYLOAD_BUFFER, NULL);
563 gst_buffer_new_and_alloc ((guint) GST_DP_HEADER_PAYLOAD_LENGTH (header));
564 GST_BUFFER_TIMESTAMP (buffer) = GST_DP_HEADER_TIMESTAMP (header);
565 GST_BUFFER_DURATION (buffer) = GST_DP_HEADER_DURATION (header);
566 GST_BUFFER_OFFSET (buffer) = GST_DP_HEADER_OFFSET (header);
567 GST_BUFFER_OFFSET_END (buffer) = GST_DP_HEADER_OFFSET_END (header);
568 GST_BUFFER_FLAGS (buffer) = GST_DP_HEADER_BUFFER_FLAGS (header);
574 * gst_dp_caps_from_packet:
575 * @header_length: the length of the packet header
576 * @header: the byte array of the packet header
577 * @payload: the byte array of the packet payload
579 * Creates a newly allocated #GstCaps from the given packet.
581 * Returns: A #GstCaps containing the caps represented in the packet,
582 * or NULL if the packet could not be converted.
585 gst_dp_caps_from_packet (guint header_length, const guint8 * header,
586 const guint8 * payload)
591 g_return_val_if_fail (header, NULL);
592 g_return_val_if_fail (payload, NULL);
593 g_return_val_if_fail (GST_DP_HEADER_PAYLOAD_TYPE (header) ==
594 GST_DP_PAYLOAD_CAPS, NULL);
596 string = g_strndup ((gchar *) payload, GST_DP_HEADER_PAYLOAD_LENGTH (header));
597 caps = gst_caps_from_string (string);
603 gst_dp_event_from_packet_0_2 (guint header_length, const guint8 * header,
604 const guint8 * payload)
606 GstEvent *event = NULL;
609 type = GST_DP_HEADER_PAYLOAD_TYPE (header) - GST_DP_PAYLOAD_EVENT_NONE;
611 case GST_EVENT_UNKNOWN:
612 GST_WARNING ("Unknown event, ignoring");
615 case GST_EVENT_FLUSH_START:
616 case GST_EVENT_FLUSH_STOP:
617 case GST_EVENT_NEWSEGMENT:
618 event = gst_event_new_custom (type, NULL);
619 GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
626 GstSeekType cur_type, stop_type;
629 /* FIXME, read rate */
631 format = (GstFormat) GST_READ_UINT32_BE (payload);
632 flags = (GstSeekFlags) GST_READ_UINT32_BE (payload + 4);
633 cur_type = (GstSeekType) GST_READ_UINT32_BE (payload + 8);
634 cur = (gint64) GST_READ_UINT64_BE (payload + 12);
635 stop_type = (GstSeekType) GST_READ_UINT32_BE (payload + 20);
636 stop = (gint64) GST_READ_UINT64_BE (payload + 24);
638 event = gst_event_new_seek (rate, format, flags, cur_type, cur,
640 GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
644 case GST_EVENT_NAVIGATION:
646 GST_WARNING ("Unhandled event type %d, ignoring", type);
649 GST_WARNING ("Unknown event type %d, ignoring", type);
657 gst_dp_event_from_packet_1_0 (guint header_length, const guint8 * header,
658 const guint8 * payload)
660 GstEvent *event = NULL;
665 type = GST_DP_HEADER_PAYLOAD_TYPE (header) - GST_DP_PAYLOAD_EVENT_NONE;
666 string = g_strndup ((gchar *) payload, GST_DP_HEADER_PAYLOAD_LENGTH (header));
667 s = gst_structure_from_string (string, NULL);
671 event = gst_event_new_custom (type, s);
677 * gst_dp_event_from_packet:
678 * @header_length: the length of the packet header
679 * @header: the byte array of the packet header
680 * @payload: the byte array of the packet payload
682 * Creates a newly allocated #GstEvent from the given packet.
684 * Returns: A #GstEvent if the event was successfully created,
685 * or NULL if an event could not be read from the payload.
688 gst_dp_event_from_packet (guint header_length, const guint8 * header,
689 const guint8 * payload)
693 g_return_val_if_fail (header, NULL);
695 major = GST_DP_HEADER_MAJOR_VERSION (header);
696 minor = GST_DP_HEADER_MINOR_VERSION (header);
698 if (major == 0 && minor == 2)
699 return gst_dp_event_from_packet_0_2 (header_length, header, payload);
700 else if (major == 1 && minor == 0)
701 return gst_dp_event_from_packet_1_0 (header_length, header, payload);
703 GST_ERROR ("Unknown GDP version %d.%d", major, minor);
709 * gst_dp_validate_header:
710 * @header_length: the length of the packet header
711 * @header: the byte array of the packet header
713 * Validates the given packet header by checking the CRC checksum.
715 * Returns: %TRUE if the CRC matches, or no CRC checksum is present.
718 gst_dp_validate_header (guint header_length, const guint8 * header)
720 guint16 crc_read, crc_calculated;
722 if (!(GST_DP_HEADER_FLAGS (header) & GST_DP_HEADER_FLAG_CRC_HEADER))
724 crc_read = GST_DP_HEADER_CRC_HEADER (header);
725 /* don't include the last two crc fields for the crc check */
726 crc_calculated = gst_dp_crc (header, header_length - 4);
727 if (crc_read != crc_calculated) {
728 GST_WARNING ("header crc mismatch: read %02x, calculated %02x", crc_read,
732 GST_LOG ("header crc validation: %02x", crc_read);
737 * gst_dp_validate_payload:
738 * @header_length: the length of the packet header
739 * @header: the byte array of the packet header
740 * @payload: the byte array of the packet payload
742 * Validates the given packet payload using the given packet header
743 * by checking the CRC checksum.
745 * Returns: %TRUE if the CRC matches, or no CRC checksum is present.
748 gst_dp_validate_payload (guint header_length, const guint8 * header,
749 const guint8 * payload)
751 guint16 crc_read, crc_calculated;
753 if (!(GST_DP_HEADER_FLAGS (header) & GST_DP_HEADER_FLAG_CRC_PAYLOAD))
755 crc_read = GST_DP_HEADER_CRC_PAYLOAD (header);
756 crc_calculated = gst_dp_crc (payload, GST_DP_HEADER_PAYLOAD_LENGTH (header));
757 if (crc_read != crc_calculated) {
758 GST_WARNING ("payload crc mismatch: read %02x, calculated %02x", crc_read,
762 GST_LOG ("payload crc validation: %02x", crc_read);
767 * gst_dp_validate_packet:
768 * @header_length: the length of the packet header
769 * @header: the byte array of the packet header
770 * @payload: the byte array of the packet payload
772 * Validates the given packet by checking version information and checksums.
774 * Returns: %TRUE if the packet validates.
777 gst_dp_validate_packet (guint header_length, const guint8 * header,
778 const guint8 * payload)
780 if (!gst_dp_validate_header (header_length, header))
782 if (!gst_dp_validate_payload (header_length, header, payload))
789 * gst_dp_packetizer_new:
790 * @version: the #GstDPVersion of the protocol to packetize for.
792 * Creates a new packetizer.
794 * Returns: a newly allocated #GstDPPacketizer
797 gst_dp_packetizer_new (GstDPVersion version)
799 GstDPPacketizer *ret;
801 ret = g_malloc0 (sizeof (GstDPPacketizer));
802 ret->version = version;
805 case GST_DP_VERSION_0_2:
806 ret->header_from_buffer = gst_dp_header_from_buffer;
807 ret->packet_from_caps = gst_dp_packet_from_caps;
808 ret->packet_from_event = gst_dp_packet_from_event;
810 case GST_DP_VERSION_1_0:
811 ret->header_from_buffer = gst_dp_header_from_buffer_1_0;
812 ret->packet_from_caps = gst_dp_packet_from_caps_1_0;
813 ret->packet_from_event = gst_dp_packet_from_event_1_0;
825 * gst_dp_packetizer_free:
826 * @packetizer: the #GstDPPacketizer to free.
828 * Free the given packetizer.
831 gst_dp_packetizer_free (GstDPPacketizer * packetizer)