mpegts: ABI/API break: Use GPtrArray instead of GArray
authorEdward Hervey <edward@collabora.com>
Wed, 21 Aug 2013 06:40:16 +0000 (08:40 +0200)
committerEdward Hervey <edward@collabora.com>
Wed, 21 Aug 2013 06:59:42 +0000 (08:59 +0200)
While it was a great idea, various g-i based bindings don't support
GArray with entries greater than sizeof(gpointer) :(

So let's just make everybody happy by just using GPtrArray.

And since we're breaking the API, also rename the various descriptor fields
to no longer have the descriptor_ prefix.

It does cost a bit more in terms of memory/cpu usage, but makes it usable
from bindings.

gst-libs/gst/mpegts/gst-dvb-descriptor.c
gst-libs/gst/mpegts/gst-dvb-section.c
gst-libs/gst/mpegts/gst-dvb-section.h
gst-libs/gst/mpegts/gstmpegtsdescriptor.c
gst-libs/gst/mpegts/gstmpegtsdescriptor.h
gst-libs/gst/mpegts/gstmpegtssection.c
gst-libs/gst/mpegts/gstmpegtssection.h
tests/examples/mpegts/ts-parser.c

index 17b2845..5f2faf2 100644 (file)
@@ -67,12 +67,11 @@ gboolean
 gst_mpegts_descriptor_parse_dvb_network_name (const GstMpegTsDescriptor *
     descriptor, gchar ** name)
 {
-  g_return_val_if_fail (descriptor != NULL
-      && descriptor->descriptor_data != NULL, FALSE);
-  g_return_val_if_fail (descriptor->descriptor_tag == 0x40, FALSE);
+  g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
+  g_return_val_if_fail (descriptor->tag == 0x40, FALSE);
 
-  *name = get_encoding_and_convert ((gchar *) descriptor->descriptor_data + 2,
-      descriptor->descriptor_data[1]);
+  *name = get_encoding_and_convert ((gchar *) descriptor->data + 2,
+      descriptor->data[1]);
   return TRUE;
 }
 
@@ -93,12 +92,11 @@ gst_mpegts_descriptor_parse_satellite_delivery_system (const GstMpegTsDescriptor
   guint8 *data;
   guint8 tmp;
 
-  g_return_val_if_fail (descriptor != NULL
-      && descriptor->descriptor_data != NULL, FALSE);
+  g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
   g_return_val_if_fail (res != NULL, FALSE);
-  g_return_val_if_fail (descriptor->descriptor_tag == 0x43, FALSE);
+  g_return_val_if_fail (descriptor->tag == 0x43, FALSE);
 
-  data = (guint8 *) descriptor->descriptor_data + 2;
+  data = (guint8 *) descriptor->data + 2;
 
 #define BCD_UN(a) ((a) & 0x0f)
 #define BCD_DEC(a) (((a) >> 4) & 0x0f)
@@ -169,12 +167,11 @@ gst_mpegts_descriptor_parse_cable_delivery_system (const GstMpegTsDescriptor *
 {
   guint8 *data;
 
-  g_return_val_if_fail (descriptor != NULL
-      && descriptor->descriptor_data != NULL, FALSE);
+  g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
   g_return_val_if_fail (res != NULL, FALSE);
-  g_return_val_if_fail (descriptor->descriptor_tag == 0x44, FALSE);
+  g_return_val_if_fail (descriptor->tag == 0x44, FALSE);
 
-  data = (guint8 *) descriptor->descriptor_data + 2;
+  data = (guint8 *) descriptor->data + 2;
   /* BCD in MHz, decimal place after the fourth character */
   res->frequency = BCD_32 (data) * 100;
   data += 5;
@@ -235,11 +232,10 @@ gst_mpegts_descriptor_parse_dvb_service (const GstMpegTsDescriptor *
 {
   guint8 *data;
 
-  g_return_val_if_fail (descriptor != NULL
-      && descriptor->descriptor_data != NULL, FALSE);
-  g_return_val_if_fail (descriptor->descriptor_tag == 0x48, FALSE);
+  g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
+  g_return_val_if_fail (descriptor->tag == 0x48, FALSE);
 
-  data = (guint8 *) descriptor->descriptor_data + 2;
+  data = (guint8 *) descriptor->data + 2;
 
   if (service_type)
     *service_type = *data;
@@ -271,11 +267,10 @@ gst_mpegts_descriptor_parse_dvb_short_event (const GstMpegTsDescriptor *
 {
   guint8 *data;
 
-  g_return_val_if_fail (descriptor != NULL
-      && descriptor->descriptor_data != NULL, FALSE);
-  g_return_val_if_fail (descriptor->descriptor_tag == 0x4D, FALSE);
+  g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
+  g_return_val_if_fail (descriptor->tag == 0x4D, FALSE);
 
-  data = (guint8 *) descriptor->descriptor_data + 2;
+  data = (guint8 *) descriptor->data + 2;
 
   if (language_code) {
     *language_code = g_malloc0 (4);
index 48facdd..0d9b203 100644 (file)
@@ -98,8 +98,13 @@ _parse_utc_time (guint8 * data)
 static GstMpegTsEITEvent *
 _gst_mpegts_eit_event_copy (GstMpegTsEITEvent * eit)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsEITEvent *copy;
+
+  copy = g_slice_dup (GstMpegTsEITEvent, eit);
+  copy->start_time = gst_date_time_ref (eit->start_time);
+  copy->descriptors = g_ptr_array_ref (eit->descriptors);
+
+  return copy;
 }
 
 static void
@@ -107,7 +112,7 @@ _gst_mpegts_eit_event_free (GstMpegTsEITEvent * eit)
 {
   if (eit->start_time)
     gst_date_time_unref (eit->start_time);
-  g_array_unref (eit->descriptors);
+  g_ptr_array_unref (eit->descriptors);
   g_slice_free (GstMpegTsEITEvent, eit);
 }
 
@@ -118,8 +123,12 @@ G_DEFINE_BOXED_TYPE (GstMpegTsEITEvent, gst_mpegts_eit_event,
 static GstMpegTsEIT *
 _gst_mpegts_eit_copy (GstMpegTsEIT * eit)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsEIT *copy;
+
+  copy = g_slice_dup (GstMpegTsEIT, eit);
+  copy->events = g_ptr_array_ref (eit->events);
+
+  return copy;
 }
 
 static void
@@ -247,14 +256,18 @@ gst_mpegts_section_get_eit (GstMpegTsSection * section)
 static GstMpegTsBATStream *
 _gst_mpegts_bat_stream_copy (GstMpegTsBATStream * bat)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsBATStream *copy;
+
+  copy = g_slice_dup (GstMpegTsBATStream, bat);
+  copy->descriptors = g_ptr_array_ref (bat->descriptors);
+
+  return copy;
 }
 
 static void
 _gst_mpegts_bat_stream_free (GstMpegTsBATStream * bat)
 {
-  g_array_unref (bat->descriptors);
+  g_ptr_array_unref (bat->descriptors);
   g_slice_free (GstMpegTsBATStream, bat);
 }
 
@@ -265,14 +278,19 @@ G_DEFINE_BOXED_TYPE (GstMpegTsBATStream, gst_mpegts_bat_stream,
 static GstMpegTsBAT *
 _gst_mpegts_bat_copy (GstMpegTsBAT * bat)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsBAT *copy;
+
+  copy = g_slice_dup (GstMpegTsBAT, bat);
+  copy->descriptors = g_ptr_array_ref (bat->descriptors);
+  copy->streams = g_ptr_array_ref (bat->streams);
+
+  return copy;
 }
 
 static void
 _gst_mpegts_bat_free (GstMpegTsBAT * bat)
 {
-  g_array_unref (bat->descriptors);
+  g_ptr_array_unref (bat->descriptors);
   g_ptr_array_unref (bat->streams);
   g_slice_free (GstMpegTsBAT, bat);
 }
@@ -414,14 +432,18 @@ gst_mpegts_section_get_bat (GstMpegTsSection * section)
 static GstMpegTsNITStream *
 _gst_mpegts_nit_stream_copy (GstMpegTsNITStream * nit)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsNITStream *copy;
+
+  copy = g_slice_dup (GstMpegTsNITStream, nit);
+  copy->descriptors = g_ptr_array_ref (nit->descriptors);
+
+  return copy;
 }
 
 static void
 _gst_mpegts_nit_stream_free (GstMpegTsNITStream * nit)
 {
-  g_array_unref (nit->descriptors);
+  g_ptr_array_unref (nit->descriptors);
   g_slice_free (GstMpegTsNITStream, nit);
 }
 
@@ -432,14 +454,18 @@ G_DEFINE_BOXED_TYPE (GstMpegTsNITStream, gst_mpegts_nit_stream,
 static GstMpegTsNIT *
 _gst_mpegts_nit_copy (GstMpegTsNIT * nit)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsNIT *copy = g_slice_dup (GstMpegTsNIT, nit);
+
+  copy->descriptors = g_ptr_array_ref (nit->descriptors);
+  copy->streams = g_ptr_array_ref (nit->streams);
+
+  return copy;
 }
 
 static void
 _gst_mpegts_nit_free (GstMpegTsNIT * nit)
 {
-  g_array_unref (nit->descriptors);
+  g_ptr_array_unref (nit->descriptors);
   g_ptr_array_unref (nit->streams);
   g_slice_free (GstMpegTsNIT, nit);
 }
@@ -584,14 +610,17 @@ gst_mpegts_section_get_nit (GstMpegTsSection * section)
 static GstMpegTsSDTService *
 _gst_mpegts_sdt_service_copy (GstMpegTsSDTService * sdt)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsSDTService *copy = g_slice_dup (GstMpegTsSDTService, sdt);
+
+  copy->descriptors = g_ptr_array_ref (sdt->descriptors);
+
+  return copy;
 }
 
 static void
 _gst_mpegts_sdt_service_free (GstMpegTsSDTService * sdt)
 {
-  g_array_unref (sdt->descriptors);
+  g_ptr_array_unref (sdt->descriptors);
   g_slice_free (GstMpegTsSDTService, sdt);
 }
 
@@ -602,8 +631,11 @@ G_DEFINE_BOXED_TYPE (GstMpegTsSDTService, gst_mpegts_sdt_service,
 static GstMpegTsSDT *
 _gst_mpegts_sdt_copy (GstMpegTsSDT * sdt)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsSDT *copy = g_slice_dup (GstMpegTsSDT, sdt);
+
+  copy->services = g_ptr_array_ref (sdt->services);
+
+  return copy;
 }
 
 static void
@@ -769,8 +801,13 @@ gst_mpegts_section_get_tdt (GstMpegTsSection * section)
 static GstMpegTsTOT *
 _gst_mpegts_tot_copy (GstMpegTsTOT * tot)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsTOT *copy = g_slice_dup (GstMpegTsTOT, tot);
+
+  if (tot->utc_time)
+    copy->utc_time = gst_date_time_ref (tot->utc_time);
+  copy->descriptors = g_ptr_array_ref (tot->descriptors);
+
+  return copy;
 }
 
 static void
@@ -778,7 +815,7 @@ _gst_mpegts_tot_free (GstMpegTsTOT * tot)
 {
   if (tot->utc_time)
     gst_date_time_unref (tot->utc_time);
-  g_array_unref (tot->descriptors);
+  g_ptr_array_unref (tot->descriptors);
   g_slice_free (GstMpegTsTOT, tot);
 }
 
index ebee434..5023182 100644 (file)
@@ -137,7 +137,7 @@ struct _GstMpegTsNITStream
   guint16  transport_stream_id;
   guint16  original_network_id;
 
-  GArray  *descriptors;
+  GPtrArray  *descriptors;
 };
 
 /**
@@ -155,7 +155,7 @@ struct _GstMpegTsNIT
 {
   gboolean   actual_network;
 
-  GArray    *descriptors;
+  GPtrArray    *descriptors;
 
   GPtrArray *streams;
 };
@@ -178,7 +178,7 @@ struct _GstMpegTsBATStream
   guint16   transport_stream_id;
   guint16   original_network_id;
 
-  GArray   *descriptors;
+  GPtrArray   *descriptors;
 };
 
 /**
@@ -190,7 +190,7 @@ struct _GstMpegTsBATStream
  */
 struct _GstMpegTsBAT
 {
-  GArray     *descriptors;
+  GPtrArray     *descriptors;
 
   GPtrArray  *streams;
 };
@@ -216,7 +216,7 @@ struct _GstMpegTsSDTService
   GstMpegTsRunningStatus running_status;
   gboolean   free_CA_mode;
 
-  GArray    *descriptors;
+  GPtrArray    *descriptors;
 };
 
 /**
@@ -260,7 +260,7 @@ struct _GstMpegTsEITEvent
   GstMpegTsRunningStatus running_status;
   gboolean     free_CA_mode;
 
-  GArray      *descriptors;
+  GPtrArray      *descriptors;
 };
 
 /**
@@ -302,7 +302,7 @@ struct _GstMpegTsTOT
 {
   GstDateTime   *utc_time;
 
-  GArray        *descriptors;
+  GPtrArray        *descriptors;
 };
 
 GType gst_mpegts_tot_get_type (void);
index f890b0a..16a7741 100644 (file)
@@ -465,6 +465,27 @@ failed:
   }
 }
 
+static GstMpegTsDescriptor *
+_copy_descriptor (GstMpegTsDescriptor * desc)
+{
+  GstMpegTsDescriptor *copy;
+
+  copy = g_slice_dup (GstMpegTsDescriptor, desc);
+  copy->data = g_memdup (desc->data, desc->length + 2);
+
+  return copy;
+}
+
+static void
+_free_descriptor (GstMpegTsDescriptor * desc)
+{
+  g_free ((gpointer) desc->data);
+  g_slice_free (GstMpegTsDescriptor, desc);
+}
+
+G_DEFINE_BOXED_TYPE (GstMpegTsDescriptor, gst_mpegts_descriptor,
+    (GBoxedCopyFunc) _copy_descriptor, (GBoxedFreeFunc) _free_descriptor);
+
 /**
  * gst_mpegts_parse_descriptors:
  * @buffer: (transfer none): descriptors to parse
@@ -479,20 +500,22 @@ failed:
  * array of the parsed descriptors or %NULL if there was an error.
  * Release with #g_array_unref when done with it.
  */
-GArray *
+GPtrArray *
 gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len)
 {
-  GArray *res;
+  GPtrArray *res;
   guint8 length;
   guint8 *data;
   guint i, nb_desc = 0;
 
   /* fast-path */
   if (buf_len == 0)
-    return g_array_new (FALSE, FALSE, sizeof (GstMpegTsDescriptor));
+    return g_ptr_array_new ();
 
   data = buffer;
 
+  GST_MEMDUMP ("Full descriptor array", buffer, buf_len);
+
   while (data - buffer < buf_len) {
     data++;                     /* skip tag */
     length = *data++;
@@ -516,26 +539,28 @@ gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len)
     return NULL;
   }
 
-  res = g_array_sized_new (FALSE, FALSE, sizeof (GstMpegTsDescriptor), nb_desc);
+  res = g_ptr_array_new_full (nb_desc + 1, (GDestroyNotify) _free_descriptor);
 
   data = buffer;
 
   for (i = 0; i < nb_desc; i++) {
-    GstMpegTsDescriptor *desc = &g_array_index (res, GstMpegTsDescriptor, i);
-
-    desc->descriptor_data = data;
-    desc->descriptor_tag = *data++;
-    desc->descriptor_length = *data++;
-    GST_LOG ("descriptor 0x%02x length:%d", desc->descriptor_tag,
-        desc->descriptor_length);
-    GST_MEMDUMP ("descriptor", desc->descriptor_data + 2,
-        desc->descriptor_length);
-    /* Adjust for extended descriptors */
-    if (G_UNLIKELY (desc->descriptor_tag == 0x7f)) {
-      desc->descriptor_tag_extension = *data++;
-      desc->descriptor_length -= 1;
-    }
-    data += desc->descriptor_length;
+    GstMpegTsDescriptor *desc = g_slice_new0 (GstMpegTsDescriptor);
+
+    desc->data = data;
+    desc->tag = *data++;
+    desc->length = *data++;
+    /* Copy the data now that we known the size */
+    desc->data = g_memdup (desc->data, desc->length + 2);
+    GST_LOG ("descriptor 0x%02x length:%d", desc->tag, desc->length);
+    GST_MEMDUMP ("descriptor", desc->data + 2, desc->length);
+    /* extended descriptors */
+    if (G_UNLIKELY (desc->tag == 0x7f))
+      desc->tag_extension = *data;
+
+    data += desc->length;
+
+    /* Set the descriptor in the array */
+    g_ptr_array_index (res, i) = desc;
   }
 
   res->len = nb_desc;
@@ -557,7 +582,7 @@ gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len)
  * Returns: (transfer none): the first descriptor matchin @tag, else %NULL.
  */
 const GstMpegTsDescriptor *
-gst_mpegts_find_descriptor (GArray * descriptors, guint8 tag)
+gst_mpegts_find_descriptor (GPtrArray * descriptors, guint8 tag)
 {
   guint i, nb_desc;
 
@@ -565,41 +590,13 @@ gst_mpegts_find_descriptor (GArray * descriptors, guint8 tag)
 
   nb_desc = descriptors->len;
   for (i = 0; i < nb_desc; i++) {
-    GstMpegTsDescriptor *desc =
-        &g_array_index (descriptors, GstMpegTsDescriptor, i);
-    if (desc->descriptor_tag == tag)
+    GstMpegTsDescriptor *desc = g_ptr_array_index (descriptors, i);
+    if (desc->tag == tag)
       return (const GstMpegTsDescriptor *) desc;
   }
   return NULL;
 }
 
-static GstMpegTsDescriptor *
-_copy_descriptor (GstMpegTsDescriptor * desc)
-{
-  GstMpegTsDescriptor *copy;
-
-  copy = g_new0 (GstMpegTsDescriptor, 1);
-  copy->descriptor_tag = desc->descriptor_tag;
-  copy->descriptor_tag_extension = desc->descriptor_tag_extension;
-  copy->descriptor_length = desc->descriptor_length;
-  copy->descriptor_data =
-      g_memdup (desc->descriptor_data, desc->descriptor_length);
-
-  return copy;
-}
-
-/* This freefunc will only ever be used with descriptors returned by the 
- * above function. That is why we free the descriptor data (unlike the
- * descriptors created in _parse_descriptors()) */
-static void
-_free_descriptor (GstMpegTsDescriptor * desc)
-{
-  g_free ((gpointer) desc->descriptor_data);
-  g_free (desc);
-}
-
-G_DEFINE_BOXED_TYPE (GstMpegTsDescriptor, gst_mpegts_descriptor,
-    (GBoxedCopyFunc) _copy_descriptor, (GBoxedFreeFunc) _free_descriptor);
 
 /* GST_MTS_DESC_ISO_639_LANGUAGE (0x0A) */
 /**
@@ -621,14 +618,13 @@ gst_mpegts_descriptor_parse_iso_639_language (const GstMpegTsDescriptor *
   guint i;
   guint8 *data;
 
-  g_return_val_if_fail (descriptor != NULL
-      && descriptor->descriptor_data != NULL, FALSE);
+  g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
   g_return_val_if_fail (res != NULL, FALSE);
-  g_return_val_if_fail (descriptor->descriptor_tag == 0x0A, FALSE);
+  g_return_val_if_fail (descriptor->tag == 0x0A, FALSE);
 
-  data = (guint8 *) descriptor->descriptor_data + 2;
+  data = (guint8 *) descriptor->data + 2;
   /* Each language is 3 + 1 bytes */
-  res->nb_language = descriptor->descriptor_length / 4;
+  res->nb_language = descriptor->length / 4;
   for (i = 0; i < res->nb_language; i++) {
     memcpy (res->language[i], data, 3);
     res->audio_type[i] = data[3];
@@ -654,12 +650,11 @@ gst_mpegts_descriptor_parse_logical_channel (const GstMpegTsDescriptor *
   guint i;
   guint8 *data;
 
-  g_return_val_if_fail (descriptor != NULL
-      && descriptor->descriptor_data != NULL, FALSE);
-  g_return_val_if_fail (descriptor->descriptor_tag == 0x83, FALSE);
+  g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
+  g_return_val_if_fail (descriptor->tag == 0x83, FALSE);
 
-  data = (guint8 *) descriptor->descriptor_data;
-  res->nb_channels = descriptor->descriptor_length / 4;
+  data = (guint8 *) descriptor->data;
+  res->nb_channels = descriptor->length / 4;
 
   for (i = 0; i < res->nb_channels; i++) {
     res->channels[i].service_id = GST_READ_UINT16_BE (data);
index 2ac27b1..c976cc1 100644 (file)
@@ -239,24 +239,25 @@ GType gst_mpegts_descriptor_get_type (void);
 
 /**
  * GstMpegTsDescriptor:
- * @descriptor_tag: the type of descriptor
- * @descriptor_tag_extension: the extended type (if @descriptor_tag is 0x7f)
- * @descriptor_length: the length of the descriptor content (excluding tag/length field)
- * @descriptor_data: the full descriptor data (including tag, extension, length)
+ * @tag: the type of descriptor
+ * @tag_extension: the extended type (if @descriptor_tag is 0x7f)
+ * @length: the length of the descriptor content (excluding tag/length field)
+ * @data: the full descriptor data (including tag, extension, length). The first
+ * two bytes are the @tag and @tag_extension.
  *
  * Mpeg-TS descriptor (ISO/IEC 13818-1).
  */
 struct _GstMpegTsDescriptor
 {
-  guint8 descriptor_tag;
-  guint8 descriptor_tag_extension;
-  guint8 descriptor_length;
-  const guint8 *descriptor_data;
+  guint8 tag;
+  guint8 tag_extension;
+  guint8 length;
+  const guint8 *data;
 };
 
-GArray *gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len);
+GPtrArray *gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len);
 
-const GstMpegTsDescriptor * gst_mpegts_find_descriptor (GArray *descriptors,
+const GstMpegTsDescriptor * gst_mpegts_find_descriptor (GPtrArray *descriptors,
                                                        guint8 tag);
 
 /* GST_MTS_DESC_ISO_639_LANGUAGE (0x0A) */
index 1a43195..6b6b3ec 100644 (file)
@@ -316,12 +316,27 @@ gst_message_new_mpegts_section (GstObject * parent, GstMpegTsSection * section)
   return msg;
 }
 
+static GstMpegTsPatProgram *
+_mpegts_pat_program_copy (GstMpegTsPatProgram * orig)
+{
+  return g_slice_dup (GstMpegTsPatProgram, orig);
+}
+
+static void
+_mpegts_pat_program_free (GstMpegTsPatProgram * orig)
+{
+  g_slice_free (GstMpegTsPatProgram, orig);
+}
+
+G_DEFINE_BOXED_TYPE (GstMpegTsPatProgram, gst_mpegts_pat_program,
+    (GBoxedCopyFunc) _mpegts_pat_program_copy,
+    (GFreeFunc) _mpegts_pat_program_free);
 
 /* Program Association Table */
 static gpointer
 _parse_pat (GstMpegTsSection * section)
 {
-  GArray *pat;
+  GPtrArray *pat;
   guint16 i = 0, nb_programs;
   GstMpegTsPatProgram *program;
   guint8 *data, *end;
@@ -335,24 +350,26 @@ _parse_pat (GstMpegTsSection * section)
   /* Initialize program list */
   nb_programs = (end - 4 - data) / 4;
   pat =
-      g_array_sized_new (FALSE, FALSE, sizeof (GstMpegTsPatProgram),
-      nb_programs);
+      g_ptr_array_new_full (nb_programs,
+      (GDestroyNotify) _mpegts_pat_program_free);
 
   while (data < end - 4) {
-    program = &g_array_index (pat, GstMpegTsPatProgram, i);
+    program = g_slice_new0 (GstMpegTsPatProgram);
     program->program_number = GST_READ_UINT16_BE (data);
     data += 2;
 
     program->network_or_program_map_PID = GST_READ_UINT16_BE (data) & 0x1FFF;
     data += 2;
 
+    g_ptr_array_index (pat, i) = program;
+
     i++;
   }
   pat->len = nb_programs;
 
   if (data != end - 4) {
     GST_ERROR ("at the end of PAT data != end - 4");
-    g_array_unref (pat);
+    g_ptr_array_unref (pat);
 
     return NULL;
   }
@@ -375,7 +392,7 @@ _parse_pat (GstMpegTsSection * section)
  * #GstMpegTsPatProgram contained in the section, or %NULL if an error
  * happened. Release with #g_ptr_array_unref when done.
  */
-GArray *
+GPtrArray *
 gst_mpegts_section_get_pat (GstMpegTsSection * section)
 {
   g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_PAT, NULL);
@@ -384,10 +401,10 @@ gst_mpegts_section_get_pat (GstMpegTsSection * section)
   if (!section->cached_parsed)
     section->cached_parsed =
         __common_desc_checks (section, 12, _parse_pat,
-        (GDestroyNotify) g_array_unref);
+        (GDestroyNotify) g_ptr_array_unref);
 
   if (section->cached_parsed)
-    return g_array_ref ((GArray *) section->cached_parsed);
+    return g_ptr_array_ref ((GPtrArray *) section->cached_parsed);
   return NULL;
 }
 
@@ -397,14 +414,18 @@ gst_mpegts_section_get_pat (GstMpegTsSection * section)
 static GstMpegTsPMTStream *
 _gst_mpegts_pmt_stream_copy (GstMpegTsPMTStream * pmt)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsPMTStream *copy;
+
+  copy = g_slice_dup (GstMpegTsPMTStream, pmt);
+  copy->descriptors = g_ptr_array_ref (pmt->descriptors);
+
+  return copy;
 }
 
 static void
 _gst_mpegts_pmt_stream_free (GstMpegTsPMTStream * pmt)
 {
-  g_array_unref (pmt->descriptors);
+  g_ptr_array_unref (pmt->descriptors);
   g_slice_free (GstMpegTsPMTStream, pmt);
 }
 
@@ -415,14 +436,19 @@ G_DEFINE_BOXED_TYPE (GstMpegTsPMTStream, gst_mpegts_pmt_stream,
 static GstMpegTsPMT *
 _gst_mpegts_pmt_copy (GstMpegTsPMT * pmt)
 {
-  /* FIXME : IMPLEMENT */
-  return NULL;
+  GstMpegTsPMT *copy;
+
+  copy = g_slice_dup (GstMpegTsPMT, pmt);
+  copy->descriptors = g_ptr_array_ref (pmt->descriptors);
+  copy->streams = g_ptr_array_ref (pmt->streams);
+
+  return copy;
 }
 
 static void
 _gst_mpegts_pmt_free (GstMpegTsPMT * pmt)
 {
-  g_array_unref (pmt->descriptors);
+  g_ptr_array_unref (pmt->descriptors);
   g_ptr_array_unref (pmt->streams);
   g_slice_free (GstMpegTsPMT, pmt);
 }
@@ -564,7 +590,7 @@ _parse_cat (GstMpegTsSection * section)
  * #GstMpegTsDescriptor contained in the section, or %NULL if an error
  * happened. Release with #g_array_unref when done.
  */
-GArray *
+GPtrArray *
 gst_mpegts_section_get_cat (GstMpegTsSection * section)
 {
   g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_CAT, NULL);
@@ -573,10 +599,10 @@ gst_mpegts_section_get_cat (GstMpegTsSection * section)
   if (!section->cached_parsed)
     section->cached_parsed =
         __common_desc_checks (section, 12, _parse_cat,
-        (GDestroyNotify) g_array_unref);
+        (GDestroyNotify) g_ptr_array_unref);
 
   if (section->cached_parsed)
-    return g_array_ref ((GArray *) section->cached_parsed);
+    return g_ptr_array_ref ((GPtrArray *) section->cached_parsed);
   return NULL;
 }
 
@@ -591,14 +617,14 @@ gst_mpegts_section_get_cat (GstMpegTsSection * section)
  * #GstMpegTsDescriptor contained in the section, or %NULL if an error
  * happened. Release with #g_array_unref when done.
  */
-GArray *
+GPtrArray *
 gst_mpegts_section_get_tsdt (GstMpegTsSection * section)
 {
   g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_TSDT, NULL);
   g_return_val_if_fail (section->cached_parsed || section->data, NULL);
 
   if (section->cached_parsed)
-    return g_array_ref ((GArray *) section->cached_parsed);
+    return g_ptr_array_ref ((GPtrArray *) section->cached_parsed);
 
   /* FIXME : parse TSDT */
   return NULL;
index 766e0c1..c7b9677 100644 (file)
@@ -157,6 +157,8 @@ struct _GstMpegTsSection
 
 
 /* PAT */
+#define GST_TYPE_MPEGTS_PAT_PROGRAM (gst_mpegts_pat_program_get_type())
+
 typedef struct _GstMpegTsPatProgram GstMpegTsPatProgram;
 /**
  * GstMpegTsPatProgram:
@@ -171,11 +173,12 @@ struct _GstMpegTsPatProgram
   guint16 network_or_program_map_PID;
 };
 
-GArray *gst_mpegts_section_get_pat (GstMpegTsSection *section);
+GPtrArray *gst_mpegts_section_get_pat (GstMpegTsSection *section);
+GType gst_mpegts_pat_program_get_type (void);
 
 /* CAT */
 
-GArray *gst_mpegts_section_get_cat (GstMpegTsSection *section);
+GPtrArray *gst_mpegts_section_get_cat (GstMpegTsSection *section);
 
 /* PMT */
 typedef struct _GstMpegTsPMTStream GstMpegTsPMTStream;
@@ -312,7 +315,7 @@ struct _GstMpegTsPMTStream
   guint8      stream_type;
   guint16     pid;
 
-  GArray     *descriptors;
+  GPtrArray     *descriptors;
 };
 
 /**
@@ -330,7 +333,7 @@ struct _GstMpegTsPMT
 {
   guint16    pcr_pid;
 
-  GArray    *descriptors;
+  GPtrArray    *descriptors;
   GPtrArray *streams;
 };
 
@@ -341,7 +344,7 @@ const GstMpegTsPMT *gst_mpegts_section_get_pmt (GstMpegTsSection *section);
 
 /* TSDT */
 
-GArray *gst_mpegts_section_get_tsdt (GstMpegTsSection *section);
+GPtrArray *gst_mpegts_section_get_tsdt (GstMpegTsSection *section);
 
 
 /* generic */
index 26d32c2..89db16f 100644 (file)
@@ -120,20 +120,18 @@ dump_iso_639_language (GstMpegTsDescriptor * desc, guint spacing)
 
 
 static void
-dump_descriptors (GArray * descriptors, guint spacing)
+dump_descriptors (GPtrArray * descriptors, guint spacing)
 {
   guint i;
 
   for (i = 0; i < descriptors->len; i++) {
-    GstMpegTsDescriptor *desc =
-        &g_array_index (descriptors, GstMpegTsDescriptor, i);
+    GstMpegTsDescriptor *desc = g_ptr_array_index (descriptors, i);
     g_printf ("%*s [descriptor 0x%02x (%s) length:%d]\n", spacing, "",
-        desc->descriptor_tag, descriptor_name (desc->descriptor_tag),
-        desc->descriptor_length);
-    switch (desc->descriptor_tag) {
+        desc->tag, descriptor_name (desc->tag), desc->length);
+    switch (desc->tag) {
       case GST_MTS_DESC_REGISTRATION:
       {
-        const guint8 *data = desc->descriptor_data + 2;
+        const guint8 *data = desc->data + 2;
 #define SAFE_CHAR(a) (g_ascii_isalnum(a) ? a : '.')
         g_printf ("%*s   Registration : %c%c%c%c\n", spacing, "",
             SAFE_CHAR (data[0]), SAFE_CHAR (data[1]),
@@ -201,14 +199,14 @@ dump_descriptors (GArray * descriptors, guint spacing)
 static void
 dump_pat (GstMpegTsSection * section)
 {
-  GArray *pat = gst_mpegts_section_get_pat (section);
+  GPtrArray *pat = gst_mpegts_section_get_pat (section);
   guint i, len;
 
   len = pat->len;
   g_printf ("   %d program(s):\n", len);
 
   for (i = 0; i < len; i++) {
-    GstMpegTsPatProgram *patp = &g_array_index (pat, GstMpegTsPatProgram, i);
+    GstMpegTsPatProgram *patp = g_ptr_array_index (pat, i);
 
     g_print
         ("     program_number:%6d (0x%04x), network_or_program_map_PID:0x%04x\n",
@@ -216,7 +214,7 @@ dump_pat (GstMpegTsSection * section)
         patp->network_or_program_map_PID);
   }
 
-  g_array_unref (pat);
+  g_ptr_array_unref (pat);
 }
 
 static void