/*
 * mpegts.h -
 * Copyright (C) 2013 Edward Hervey
 *
 * Authors:
 *   Edward Hervey <edward@collabora.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef _GST_MPEGTS_PRIVATE_H_
#define _GST_MPEGTS_PRIVATE_H_

G_BEGIN_DECLS

GST_DEBUG_CATEGORY_EXTERN (gst_mpegts_debug);
#define GST_CAT_DEFAULT gst_mpegts_debug

G_GNUC_INTERNAL void __initialize_descriptors (void);
G_GNUC_INTERNAL guint32 _calc_crc32 (const guint8 *data, guint datalen);
G_GNUC_INTERNAL gchar *get_encoding_and_convert (const gchar *text, guint length);
G_GNUC_INTERNAL gchar *convert_lang_code (guint8 * data);
G_GNUC_INTERNAL guint8 *dvb_text_from_utf8 (const gchar * text, gsize *out_size);
G_GNUC_INTERNAL GstMpegtsDescriptor *_new_descriptor (guint8 tag, guint8 length);
G_GNUC_INTERNAL GstMpegtsDescriptor *_new_descriptor_with_extension (guint8 tag,
    guint8 tag_extension, guint8 length);
G_GNUC_INTERNAL void _packetize_descriptor_array (GPtrArray * array,
    guint8 ** out_data);
G_GNUC_INTERNAL GstMpegtsSection *_gst_mpegts_section_init (guint16 pid, guint8 table_id);
G_GNUC_INTERNAL void _packetize_common_section (GstMpegtsSection * section, gsize length);

typedef gpointer (*GstMpegtsParseFunc) (GstMpegtsSection *section);
G_GNUC_INTERNAL gpointer __common_section_checks (GstMpegtsSection *section,
						  guint minsize,
						  GstMpegtsParseFunc parsefunc,
						  GDestroyNotify destroynotify);

#define __common_desc_check_base(desc, tagtype, retval)			\
  if (G_UNLIKELY ((desc)->data == NULL)) {				\
    GST_WARNING ("Descriptor is empty (data field == NULL)");		\
    return retval;							\
  }									\
  if (G_UNLIKELY ((desc)->tag != (tagtype))) {				\
    GST_WARNING ("Wrong descriptor type (Got 0x%02x, expected 0x%02x)",	\
		 (desc)->tag, tagtype);					\
    return retval;							\
  }									\

#define __common_desc_checks(desc, tagtype, minlen, retval)		\
  __common_desc_check_base(desc, tagtype, retval);			\
  if (G_UNLIKELY ((desc)->length < (minlen))) {				\
    GST_WARNING ("Descriptor too small (Got %d, expected at least %d)",	\
		 (desc)->length, minlen);				\
    return retval;							\
  }
#define __common_desc_checks_exact(desc, tagtype, len, retval)		\
  __common_desc_check_base(desc, tagtype, retval);			\
  if (G_UNLIKELY ((desc)->length != (len))) {				\
    GST_WARNING ("Wrong descriptor size (Got %d, expected %d)",		\
		 (desc)->length, len);					\
    return retval;							\
  }

#define __common_desc_ext_check_base(desc, tagexttype, retval)          \
  if (G_UNLIKELY ((desc)->data == NULL)) {                              \
    GST_WARNING ("Descriptor is empty (data field == NULL)");           \
    return retval;                                                      \
  }                                                                     \
  if (G_UNLIKELY ((desc)->tag != 0x7f) ||                               \
    ((desc)->tag_extension != (tagexttype))) {                          \
    GST_WARNING ("Wrong descriptor type (Got 0x%02x, expected 0x%02x)", \
                 (desc)->tag_extension, tagexttype);                    \
    return retval;                                                      \
  }
#define __common_desc_ext_checks(desc, tagexttype, minlen, retval)      \
  __common_desc_ext_check_base(desc, tagexttype, retval);                    \
  if (G_UNLIKELY ((desc)->length < (minlen))) {                         \
    GST_WARNING ("Descriptor too small (Got %d, expected at least %d)", \
                 (desc)->length, minlen);                               \
    return retval;                                                      \
  }
#define __common_desc_ext_checks_exact(desc, tagexttype, len, retval)   \
  __common_desc_ext_check_base(desc, tagexttype, retval);               \
  if (G_UNLIKELY ((desc)->length != (len))) {                           \
     GST_WARNING ("Wrong descriptor size (Got %d, expected %d)",        \
                  (desc)->length, len);                                 \
     return retval;                                                     \
  }

G_END_DECLS

#endif	/* _GST_MPEGTS_PRIVATE_H_ */
