examples/ts-parser: Use the section type for descriptor identification
authorEdward Hervey <edward@centricular.com>
Mon, 14 Dec 2020 09:56:39 +0000 (10:56 +0100)
committerEdward Hervey <bilboed@bilboed.com>
Mon, 14 Dec 2020 16:57:40 +0000 (17:57 +0100)
Some descriptors can only be present in some section

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1880>

tests/examples/mpegts/ts-parser.c

index 858a0f2..b5714c8 100644 (file)
@@ -518,284 +518,311 @@ dump_dvb_extended_event (GstMpegtsDescriptor * desc, guint spacing)
   }
 }
 
+#define SAFE_CHAR(a) (g_ascii_isprint(a) ? a : '.')
+
+/* Single descriptor dump
+ * Descriptors that can only appear in specific tables should be handled before */
 static void
-dump_descriptors (GPtrArray * descriptors, guint spacing)
+dump_generic_descriptor (GstMpegtsDescriptor * desc, guint spacing)
 {
-  guint i;
-
-  for (i = 0; i < descriptors->len; i++) {
-    GstMpegtsDescriptor *desc = g_ptr_array_index (descriptors, i);
-    g_printf ("%*s [descriptor 0x%02x (%s) length:%d]\n", spacing, "",
-        desc->tag, descriptor_name (desc), desc->length);
-    if (DUMP_DESCRIPTORS)
-      dump_memory_content (desc, spacing + 2);
-    switch (desc->tag) {
-      case GST_MTS_DESC_REGISTRATION:
-      {
-        const guint8 *data = desc->data + 2;
-#define SAFE_CHAR(a) (g_ascii_isprint(a) ? a : '.')
-        g_printf ("%*s   Registration : %c%c%c%c [%02x%02x%02x%02x]\n", spacing,
-            "", SAFE_CHAR (data[0]), SAFE_CHAR (data[1]), SAFE_CHAR (data[2]),
-            SAFE_CHAR (data[3]), data[0], data[1], data[2], data[3]);
+  switch (desc->tag) {
+    case GST_MTS_DESC_REGISTRATION:
+    {
+      const guint8 *data = desc->data + 2;
+      g_printf ("%*s   Registration : %c%c%c%c [%02x%02x%02x%02x]\n", spacing,
+          "", SAFE_CHAR (data[0]), SAFE_CHAR (data[1]), SAFE_CHAR (data[2]),
+          SAFE_CHAR (data[3]), data[0], data[1], data[2], data[3]);
 
-        break;
-      }
-      case GST_MTS_DESC_CA:
-      {
-        guint16 ca_pid, ca_system_id;
-        const guint8 *private_data;
-        gsize private_data_size;
-        if (gst_mpegts_descriptor_parse_ca (desc, &ca_system_id, &ca_pid,
-                &private_data, &private_data_size)) {
-          g_printf ("%*s   CA system id : 0x%04x\n", spacing, "", ca_system_id);
-          g_printf ("%*s   CA PID       : 0x%04x\n", spacing, "", ca_pid);
-          if (private_data_size) {
-            g_printf ("%*s   Private Data :\n", spacing, "");
-            dump_memory_bytes ((guint8 *) private_data, private_data_size,
-                spacing + 2);
-          }
-        }
-        break;
-      }
-      case GST_MTS_DESC_DVB_NETWORK_NAME:
-      {
-        gchar *network_name;
-        if (gst_mpegts_descriptor_parse_dvb_network_name (desc, &network_name)) {
-          g_printf ("%*s   Network Name : %s\n", spacing, "", network_name);
-          g_free (network_name);
+      break;
+    }
+    case GST_MTS_DESC_CA:
+    {
+      guint16 ca_pid, ca_system_id;
+      const guint8 *private_data;
+      gsize private_data_size;
+      if (gst_mpegts_descriptor_parse_ca (desc, &ca_system_id, &ca_pid,
+              &private_data, &private_data_size)) {
+        g_printf ("%*s   CA system id : 0x%04x\n", spacing, "", ca_system_id);
+        g_printf ("%*s   CA PID       : 0x%04x\n", spacing, "", ca_pid);
+        if (private_data_size) {
+          g_printf ("%*s   Private Data :\n", spacing, "");
+          dump_memory_bytes ((guint8 *) private_data, private_data_size,
+              spacing + 2);
         }
-        break;
       }
-      case GST_MTS_DESC_DVB_SERVICE_LIST:
-      {
-        dump_dvb_service_list (desc, spacing + 2);
-        break;
+      break;
+    }
+    case GST_MTS_DESC_DVB_NETWORK_NAME:
+    {
+      gchar *network_name;
+      if (gst_mpegts_descriptor_parse_dvb_network_name (desc, &network_name)) {
+        g_printf ("%*s   Network Name : %s\n", spacing, "", network_name);
+        g_free (network_name);
       }
-      case GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM:
-        dump_cable_delivery_descriptor (desc, spacing + 2);
-        break;
-      case GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM:
-        dump_terrestrial_delivery (desc, spacing + 2);
-        break;
-      case GST_MTS_DESC_DVB_BOUQUET_NAME:
-      {
-        gchar *bouquet_name;
-        if (gst_mpegts_descriptor_parse_dvb_bouquet_name (desc, &bouquet_name)) {
-          g_printf ("%*s   Bouquet Name Descriptor, bouquet_name:%s\n", spacing,
-              "", bouquet_name);
-          g_free (bouquet_name);
-        }
-        break;
+      break;
+    }
+    case GST_MTS_DESC_DVB_SERVICE_LIST:
+    {
+      dump_dvb_service_list (desc, spacing + 2);
+      break;
+    }
+    case GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM:
+      dump_cable_delivery_descriptor (desc, spacing + 2);
+      break;
+    case GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM:
+      dump_terrestrial_delivery (desc, spacing + 2);
+      break;
+    case GST_MTS_DESC_DVB_BOUQUET_NAME:
+    {
+      gchar *bouquet_name;
+      if (gst_mpegts_descriptor_parse_dvb_bouquet_name (desc, &bouquet_name)) {
+        g_printf ("%*s   Bouquet Name Descriptor, bouquet_name:%s\n", spacing,
+            "", bouquet_name);
+        g_free (bouquet_name);
       }
-      case GST_MTS_DESC_DTG_LOGICAL_CHANNEL:
-        dump_logical_channel_descriptor (desc, spacing + 2);
-        break;
-      case GST_MTS_DESC_DVB_SERVICE:
-      {
-        gchar *service_name, *provider_name;
-        GstMpegtsDVBServiceType service_type;
-        if (gst_mpegts_descriptor_parse_dvb_service (desc, &service_type,
-                &service_name, &provider_name)) {
-          g_printf ("%*s   Service Descriptor, type:0x%02x (%s)\n", spacing, "",
-              service_type, enum_name (GST_TYPE_MPEGTS_DVB_SERVICE_TYPE,
-                  service_type));
-          g_printf ("%*s      service_name  : %s\n", spacing, "", service_name);
-          g_printf ("%*s      provider_name : %s\n", spacing, "",
-              provider_name);
-          g_free (service_name);
-          g_free (provider_name);
+      break;
+    }
+    case GST_MTS_DESC_DVB_SERVICE:
+    {
+      gchar *service_name, *provider_name;
+      GstMpegtsDVBServiceType service_type;
+      if (gst_mpegts_descriptor_parse_dvb_service (desc, &service_type,
+              &service_name, &provider_name)) {
+        g_printf ("%*s   Service Descriptor, type:0x%02x (%s)\n", spacing, "",
+            service_type, enum_name (GST_TYPE_MPEGTS_DVB_SERVICE_TYPE,
+                service_type));
+        g_printf ("%*s      service_name  : %s\n", spacing, "", service_name);
+        g_printf ("%*s      provider_name : %s\n", spacing, "", provider_name);
+        g_free (service_name);
+        g_free (provider_name);
 
-        }
-        break;
-      }
-      case GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME:
-      {
-        dump_multiligual_bouquet_name (desc, spacing + 2);
-        break;
-      }
-      case GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME:
-      {
-        dump_multiligual_network_name (desc, spacing + 2);
-        break;
-      }
-      case GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME:
-      {
-        dump_multiligual_service_name (desc, spacing + 2);
-        break;
-      }
-      case GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT:
-      {
-        dump_multiligual_component (desc, spacing + 2);
-        break;
       }
-      case GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER:
-      {
-        guint32 specifier;
-        guint8 len = 0, *data = NULL;
-
-        if (gst_mpegts_descriptor_parse_dvb_private_data_specifier (desc,
-                &specifier, &data, &len)) {
-          g_printf ("%*s   private_data_specifier : 0x%08x\n", spacing, "",
-              specifier);
-          if (len > 0) {
-            dump_memory_bytes (data, len, spacing + 2);
-            g_free (data);
-          }
+      break;
+    }
+    case GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME:
+    {
+      dump_multiligual_bouquet_name (desc, spacing + 2);
+      break;
+    }
+    case GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME:
+    {
+      dump_multiligual_network_name (desc, spacing + 2);
+      break;
+    }
+    case GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME:
+    {
+      dump_multiligual_service_name (desc, spacing + 2);
+      break;
+    }
+    case GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT:
+    {
+      dump_multiligual_component (desc, spacing + 2);
+      break;
+    }
+    case GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER:
+    {
+      guint32 specifier;
+      guint8 len = 0, *data = NULL;
+
+      if (gst_mpegts_descriptor_parse_dvb_private_data_specifier (desc,
+              &specifier, &data, &len)) {
+        g_printf ("%*s   private_data_specifier : 0x%08x\n", spacing, "",
+            specifier);
+        if (len > 0) {
+          dump_memory_bytes (data, len, spacing + 2);
+          g_free (data);
         }
-        break;
       }
-      case GST_MTS_DESC_DVB_FREQUENCY_LIST:
-      {
-        gboolean offset;
-        GArray *list;
-        if (gst_mpegts_descriptor_parse_dvb_frequency_list (desc, &offset,
-                &list)) {
-          guint j;
-          for (j = 0; j < list->len; j++) {
-            guint32 freq = g_array_index (list, guint32, j);
-            g_printf ("%*s   Frequency : %u %s\n", spacing, "", freq,
-                offset ? "kHz" : "Hz");
-          }
-          g_array_unref (list);
+      break;
+    }
+    case GST_MTS_DESC_DVB_FREQUENCY_LIST:
+    {
+      gboolean offset;
+      GArray *list;
+      if (gst_mpegts_descriptor_parse_dvb_frequency_list (desc, &offset, &list)) {
+        guint j;
+        for (j = 0; j < list->len; j++) {
+          guint32 freq = g_array_index (list, guint32, j);
+          g_printf ("%*s   Frequency : %u %s\n", spacing, "", freq,
+              offset ? "kHz" : "Hz");
         }
-        break;
+        g_array_unref (list);
       }
-      case GST_MTS_DESC_DVB_LINKAGE:
-        dump_linkage (desc, spacing + 2);
-        break;
-      case GST_MTS_DESC_DVB_COMPONENT:
-        dump_component (desc, spacing + 2);
-        break;
-      case GST_MTS_DESC_DVB_STREAM_IDENTIFIER:
-      {
-        guint8 tag;
-        if (gst_mpegts_descriptor_parse_dvb_stream_identifier (desc, &tag)) {
-          g_printf ("%*s   Component Tag : 0x%02x\n", spacing, "", tag);
-        }
-        break;
+      break;
+    }
+    case GST_MTS_DESC_DVB_LINKAGE:
+      dump_linkage (desc, spacing + 2);
+      break;
+    case GST_MTS_DESC_DVB_COMPONENT:
+      dump_component (desc, spacing + 2);
+      break;
+    case GST_MTS_DESC_DVB_STREAM_IDENTIFIER:
+    {
+      guint8 tag;
+      if (gst_mpegts_descriptor_parse_dvb_stream_identifier (desc, &tag)) {
+        g_printf ("%*s   Component Tag : 0x%02x\n", spacing, "", tag);
       }
-      case GST_MTS_DESC_DVB_CA_IDENTIFIER:
-      {
-        GArray *list;
-        guint j;
-        guint16 ca_id;
-        if (gst_mpegts_descriptor_parse_dvb_ca_identifier (desc, &list)) {
-          for (j = 0; j < list->len; j++) {
-            ca_id = g_array_index (list, guint16, j);
-            g_printf ("%*s   CA Identifier : 0x%04x\n", spacing, "", ca_id);
-          }
-          g_array_unref (list);
+      break;
+    }
+    case GST_MTS_DESC_DVB_CA_IDENTIFIER:
+    {
+      GArray *list;
+      guint j;
+      guint16 ca_id;
+      if (gst_mpegts_descriptor_parse_dvb_ca_identifier (desc, &list)) {
+        for (j = 0; j < list->len; j++) {
+          ca_id = g_array_index (list, guint16, j);
+          g_printf ("%*s   CA Identifier : 0x%04x\n", spacing, "", ca_id);
         }
-        break;
+        g_array_unref (list);
       }
-      case GST_MTS_DESC_DVB_CONTENT:
-        dump_content (desc, spacing + 2);
-        break;
-      case GST_MTS_DESC_DVB_PARENTAL_RATING:
-      {
-        GPtrArray *ratings;
-        guint j;
-
-        if (gst_mpegts_descriptor_parse_dvb_parental_rating (desc, &ratings)) {
-          for (j = 0; j < ratings->len; j++) {
-            GstMpegtsDVBParentalRatingItem *item =
-                g_ptr_array_index (ratings, j);
-            g_printf ("%*s   country_code : %s\n", spacing, "",
-                item->country_code);
-            g_printf ("%*s   rating age   : %d\n", spacing, "", item->rating);
-          }
-          g_ptr_array_unref (ratings);
+      break;
+    }
+    case GST_MTS_DESC_DVB_CONTENT:
+      dump_content (desc, spacing + 2);
+      break;
+    case GST_MTS_DESC_DVB_PARENTAL_RATING:
+    {
+      GPtrArray *ratings;
+      guint j;
+
+      if (gst_mpegts_descriptor_parse_dvb_parental_rating (desc, &ratings)) {
+        for (j = 0; j < ratings->len; j++) {
+          GstMpegtsDVBParentalRatingItem *item = g_ptr_array_index (ratings, j);
+          g_printf ("%*s   country_code : %s\n", spacing, "",
+              item->country_code);
+          g_printf ("%*s   rating age   : %d\n", spacing, "", item->rating);
         }
-        break;
+        g_ptr_array_unref (ratings);
       }
-      case GST_MTS_DESC_DVB_DATA_BROADCAST:
-      {
-        GstMpegtsDataBroadcastDescriptor *res;
-
-        if (gst_mpegts_descriptor_parse_dvb_data_broadcast (desc, &res)) {
-          g_printf ("%*s   data_broadcast_id : 0x%04x\n", spacing, "",
-              res->data_broadcast_id);
-          g_printf ("%*s   component_tag     : 0x%02x\n", spacing, "",
-              res->component_tag);
-          if (res->length > 0) {
-            g_printf ("%*s   selector_bytes:\n", spacing, "");
-            dump_memory_bytes (res->selector_bytes, res->length, spacing + 2);
-          }
-          g_printf ("%*s   text              : %s\n", spacing, "",
-              res->text ? res->text : "NULL");
-          gst_mpegts_dvb_data_broadcast_descriptor_free (res);
+      break;
+    }
+    case GST_MTS_DESC_DVB_DATA_BROADCAST:
+    {
+      GstMpegtsDataBroadcastDescriptor *res;
+
+      if (gst_mpegts_descriptor_parse_dvb_data_broadcast (desc, &res)) {
+        g_printf ("%*s   data_broadcast_id : 0x%04x\n", spacing, "",
+            res->data_broadcast_id);
+        g_printf ("%*s   component_tag     : 0x%02x\n", spacing, "",
+            res->component_tag);
+        if (res->length > 0) {
+          g_printf ("%*s   selector_bytes:\n", spacing, "");
+          dump_memory_bytes (res->selector_bytes, res->length, spacing + 2);
         }
-        break;
+        g_printf ("%*s   text              : %s\n", spacing, "",
+            res->text ? res->text : "NULL");
+        gst_mpegts_dvb_data_broadcast_descriptor_free (res);
       }
-      case GST_MTS_DESC_ISO_639_LANGUAGE:
-        dump_iso_639_language (desc, spacing + 2);
-        break;
-      case GST_MTS_DESC_DVB_SHORT_EVENT:
-      {
-        gchar *language_code, *event_name, *text;
-        if (gst_mpegts_descriptor_parse_dvb_short_event (desc, &language_code,
-                &event_name, &text)) {
-          g_printf ("%*s   Short Event, language_code:%s\n", spacing, "",
-              language_code);
-          g_printf ("%*s     event_name : %s\n", spacing, "", event_name);
-          g_printf ("%*s     text       : %s\n", spacing, "", text);
-          g_free (language_code);
-          g_free (event_name);
-          g_free (text);
-        }
+      break;
+    }
+    case GST_MTS_DESC_ISO_639_LANGUAGE:
+      dump_iso_639_language (desc, spacing + 2);
+      break;
+    case GST_MTS_DESC_DVB_SHORT_EVENT:
+    {
+      gchar *language_code, *event_name, *text;
+      if (gst_mpegts_descriptor_parse_dvb_short_event (desc, &language_code,
+              &event_name, &text)) {
+        g_printf ("%*s   Short Event, language_code:%s\n", spacing, "",
+            language_code);
+        g_printf ("%*s     event_name : %s\n", spacing, "", event_name);
+        g_printf ("%*s     text       : %s\n", spacing, "", text);
+        g_free (language_code);
+        g_free (event_name);
+        g_free (text);
       }
-        break;
-      case GST_MTS_DESC_DVB_EXTENDED_EVENT:
-      {
-        dump_dvb_extended_event (desc, spacing + 2);
-        break;
+    }
+      break;
+    case GST_MTS_DESC_DVB_EXTENDED_EVENT:
+    {
+      dump_dvb_extended_event (desc, spacing + 2);
+      break;
+    }
+    case GST_MTS_DESC_DVB_SUBTITLING:
+    {
+      gchar *lang;
+      guint8 type;
+      guint16 composition;
+      guint16 ancillary;
+      guint j;
+
+      for (j = 0;
+          gst_mpegts_descriptor_parse_dvb_subtitling_idx (desc, j, &lang,
+              &type, &composition, &ancillary); j++) {
+        g_printf ("%*s   Subtitling, language_code:%s\n", spacing, "", lang);
+        g_printf ("%*s      type                : %u\n", spacing, "", type);
+        g_printf ("%*s      composition page id : %u\n", spacing, "",
+            composition);
+        g_printf ("%*s      ancillary page id   : %u\n", spacing, "",
+            ancillary);
+        g_free (lang);
       }
-      case GST_MTS_DESC_DVB_SUBTITLING:
-      {
-        gchar *lang;
-        guint8 type;
-        guint16 composition;
-        guint16 ancillary;
-        guint j;
-
-        for (j = 0;
-            gst_mpegts_descriptor_parse_dvb_subtitling_idx (desc, j, &lang,
-                &type, &composition, &ancillary); j++) {
-          g_printf ("%*s   Subtitling, language_code:%s\n", spacing, "", lang);
-          g_printf ("%*s      type                : %u\n", spacing, "", type);
-          g_printf ("%*s      composition page id : %u\n", spacing, "",
-              composition);
-          g_printf ("%*s      ancillary page id   : %u\n", spacing, "",
-              ancillary);
-          g_free (lang);
-        }
+    }
+      break;
+    case GST_MTS_DESC_DVB_TELETEXT:
+    {
+      GstMpegtsDVBTeletextType type;
+      gchar *lang;
+      guint8 magazine, page_number;
+      guint j;
+
+      for (j = 0;
+          gst_mpegts_descriptor_parse_dvb_teletext_idx (desc, j, &lang, &type,
+              &magazine, &page_number); j++) {
+        g_printf ("%*s   Teletext, type:0x%02x (%s)\n", spacing, "", type,
+            enum_name (GST_TYPE_MPEGTS_DVB_TELETEXT_TYPE, type));
+        g_printf ("%*s      language    : %s\n", spacing, "", lang);
+        g_printf ("%*s      magazine    : %u\n", spacing, "", magazine);
+        g_printf ("%*s      page number : %u\n", spacing, "", page_number);
+        g_free (lang);
       }
-        break;
-      case GST_MTS_DESC_DVB_TELETEXT:
-      {
-        GstMpegtsDVBTeletextType type;
-        gchar *lang;
-        guint8 magazine, page_number;
-        guint j;
+    }
+      break;
+    default:
+      break;
+  }
+}
 
-        for (j = 0;
-            gst_mpegts_descriptor_parse_dvb_teletext_idx (desc, j, &lang, &type,
-                &magazine, &page_number); j++) {
-          g_printf ("%*s   Teletext, type:0x%02x (%s)\n", spacing, "", type,
-              enum_name (GST_TYPE_MPEGTS_DVB_TELETEXT_TYPE, type));
-          g_printf ("%*s      language    : %s\n", spacing, "", lang);
-          g_printf ("%*s      magazine    : %u\n", spacing, "", magazine);
-          g_printf ("%*s      page number : %u\n", spacing, "", page_number);
-          g_free (lang);
-        }
-      }
+static void
+dump_descriptors (GPtrArray * descriptors, guint spacing)
+{
+  guint i;
+
+  for (i = 0; i < descriptors->len; i++) {
+    GstMpegtsDescriptor *desc = g_ptr_array_index (descriptors, i);
+    g_printf ("%*s [descriptor 0x%02x (%s) length:%d]\n", spacing, "",
+        desc->tag, descriptor_name (desc), desc->length);
+    if (DUMP_DESCRIPTORS)
+      dump_memory_content (desc, spacing + 2);
+    dump_generic_descriptor (desc, spacing + 2);
+  }
+}
+
+static void
+dump_nit_descriptors (GPtrArray * descriptors, guint spacing)
+{
+  /* Descriptors that can only appear in NIT */
+  guint i;
+
+  for (i = 0; i < descriptors->len; i++) {
+    GstMpegtsDescriptor *desc = g_ptr_array_index (descriptors, i);
+    g_printf ("%*s [descriptor 0x%02x (%s) length:%d]\n", spacing, "",
+        desc->tag, descriptor_name (desc), desc->length);
+    if (DUMP_DESCRIPTORS)
+      dump_memory_content (desc, spacing + 2);
+    switch (desc->tag) {
+      case GST_MTS_DESC_DTG_LOGICAL_CHANNEL:
+        dump_logical_channel_descriptor (desc, spacing + 2);
         break;
       default:
+        dump_generic_descriptor (desc, spacing + 2);
         break;
     }
   }
 }
 
+
 static void
 dump_pat (GstMpegtsSection * section)
 {
@@ -989,7 +1016,7 @@ dump_nit (GstMpegtsSection * section)
     g_printf
         ("       transport_stream_id:0x%04x , original_network_id:0x%02x\n",
         stream->transport_stream_id, stream->original_network_id);
-    dump_descriptors (stream->descriptors, 9);
+    dump_nit_descriptors (stream->descriptors, 9);
   }
 }