diff options
-rw-r--r-- | gst-libs/gst/mpegts/gst-dvb-section.c | 316 | ||||
-rw-r--r-- | gst-libs/gst/mpegts/gst-dvb-section.h | 4 | ||||
-rw-r--r-- | gst-libs/gst/mpegts/gstmpegts-private.h | 6 | ||||
-rw-r--r-- | gst-libs/gst/mpegts/gstmpegtssection.c | 134 |
4 files changed, 255 insertions, 205 deletions
diff --git a/gst-libs/gst/mpegts/gst-dvb-section.c b/gst-libs/gst/mpegts/gst-dvb-section.c index b9904eacb..48facddcd 100644 --- a/gst-libs/gst/mpegts/gst-dvb-section.c +++ b/gst-libs/gst/mpegts/gst-dvb-section.c @@ -133,7 +133,7 @@ G_DEFINE_BOXED_TYPE (GstMpegTsEIT, gst_mpegts_eit, (GBoxedCopyFunc) _gst_mpegts_eit_copy, (GFreeFunc) _gst_mpegts_eit_free); -static GstMpegTsEIT * +static gpointer _parse_eit (GstMpegTsSection * section) { GstMpegTsEIT *eit = NULL; @@ -141,13 +141,6 @@ _parse_eit (GstMpegTsSection * section) guint8 *data, *end, *duration_ptr; guint16 descriptors_loop_length; - /* fixed header + CRC == 16 */ - if (section->section_length < 18) { - GST_WARNING ("PID %d invalid EIT size %d", - section->pid, section->section_length); - goto error; - } - eit = g_slice_new0 (GstMpegTsEIT); data = section->data; @@ -218,11 +211,11 @@ _parse_eit (GstMpegTsSection * section) goto error; } - return eit; + return (gpointer) eit; error: if (eit) - gst_mpegts_section_unref (eit); + _gst_mpegts_eit_free (eit); return NULL; @@ -243,32 +236,32 @@ gst_mpegts_section_get_eit (GstMpegTsSection * section) g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_EIT, NULL); g_return_val_if_fail (section->cached_parsed || section->data, NULL); - if (!section->cached_parsed) { - if (G_UNLIKELY (_calc_crc32 (section->data, section->section_length) != 0)) - goto bad_crc; - - section->cached_parsed = (gpointer) _parse_eit (section); - section->destroy_parsed = (GDestroyNotify) _gst_mpegts_eit_free; - if (section->cached_parsed == NULL) - goto parse_failure; - } + if (!section->cached_parsed) + section->cached_parsed = __common_desc_checks (section, 18, _parse_eit, + (GDestroyNotify) _gst_mpegts_eit_free); return (const GstMpegTsEIT *) section->cached_parsed; +} -bad_crc: - { - GST_WARNING ("Bad CRC on section"); - return NULL; - } +/* Bouquet Association Table */ +static GstMpegTsBATStream * +_gst_mpegts_bat_stream_copy (GstMpegTsBATStream * bat) +{ + /* FIXME : IMPLEMENT */ + return NULL; +} -parse_failure: - { - GST_WARNING ("Failure to parse section"); - return NULL; - } +static void +_gst_mpegts_bat_stream_free (GstMpegTsBATStream * bat) +{ + g_array_unref (bat->descriptors); + g_slice_free (GstMpegTsBATStream, bat); } -/* Bouquet Association Table */ +G_DEFINE_BOXED_TYPE (GstMpegTsBATStream, gst_mpegts_bat_stream, + (GBoxedCopyFunc) _gst_mpegts_bat_stream_copy, + (GFreeFunc) _gst_mpegts_bat_stream_free); + static GstMpegTsBAT * _gst_mpegts_bat_copy (GstMpegTsBAT * bat) { @@ -279,12 +272,143 @@ _gst_mpegts_bat_copy (GstMpegTsBAT * bat) static void _gst_mpegts_bat_free (GstMpegTsBAT * bat) { - /* FIXME: IMPLEMENT */ + g_array_unref (bat->descriptors); + g_ptr_array_unref (bat->streams); + g_slice_free (GstMpegTsBAT, bat); } G_DEFINE_BOXED_TYPE (GstMpegTsBAT, gst_mpegts_bat, (GBoxedCopyFunc) _gst_mpegts_bat_copy, (GFreeFunc) _gst_mpegts_bat_free); +static gpointer +_parse_bat (GstMpegTsSection * section) +{ + GstMpegTsBAT *bat = NULL; + guint i = 0, allocated_streams = 12; + guint8 *data, *end, *entry_begin; + guint16 descriptors_loop_length, transport_stream_loop_length; + + GST_DEBUG ("BAT"); + + bat = g_slice_new0 (GstMpegTsBAT); + + data = section->data; + end = data + section->section_length; + + /* Skip already parsed data */ + data += 8; + + descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; + + /* see if the buffer is large enough */ + if (descriptors_loop_length && (data + descriptors_loop_length > end - 4)) { + GST_WARNING ("PID %d invalid BAT descriptors loop length %d", + section->pid, descriptors_loop_length); + goto error; + } + bat->descriptors = + gst_mpegts_parse_descriptors (data, descriptors_loop_length); + if (bat->descriptors == NULL) + goto error; + data += descriptors_loop_length; + + transport_stream_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; + if (G_UNLIKELY (transport_stream_loop_length > (end - 4 - data))) { + GST_WARNING + ("PID 0x%04x invalid BAT (transport_stream_loop_length too big)", + section->pid); + goto error; + } + + bat->streams = + g_ptr_array_new_full (allocated_streams, + (GDestroyNotify) _gst_mpegts_bat_stream_free); + + /* read up to the CRC */ + while (transport_stream_loop_length - 4 > 0) { + GstMpegTsBATStream *stream = g_slice_new0 (GstMpegTsBATStream); + + g_ptr_array_add (bat->streams, stream); + + if (transport_stream_loop_length < 6) { + /* each entry must be at least 6 bytes (+ 4bytes CRC) */ + GST_WARNING ("PID %d invalid BAT entry size %d", + section->pid, transport_stream_loop_length); + goto error; + } + + entry_begin = data; + + stream->transport_stream_id = GST_READ_UINT16_BE (data); + data += 2; + + stream->original_network_id = GST_READ_UINT16_BE (data); + data += 2; + + descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x0FFF; + data += 2; + + GST_DEBUG ("descriptors_loop_length %d", descriptors_loop_length); + + if (descriptors_loop_length && (data + descriptors_loop_length > end - 4)) { + GST_WARNING + ("PID %d invalid BAT entry %d descriptors loop length %d (only have %" + G_GSIZE_FORMAT ")", section->pid, section->subtable_extension, + descriptors_loop_length, end - 4 - data); + goto error; + } + stream->descriptors = + gst_mpegts_parse_descriptors (data, descriptors_loop_length); + if (stream->descriptors == NULL) + goto error; + + data += descriptors_loop_length; + + i += 1; + transport_stream_loop_length -= data - entry_begin; + } + + if (data != end - 4) { + GST_WARNING ("PID %d invalid BAT parsed %d length %d", + section->pid, (gint) (data - section->data), section->section_length); + goto error; + } + + return (gpointer) bat; + +error: + if (bat) + _gst_mpegts_bat_free (bat); + + return NULL; +} + +/** + * gst_mpegts_section_get_bat: + * @section: a #GstMpegTsSection of type %GST_MPEGTS_SECTION_BAT + * + * Returns the #GstMpegTsBAT contained in the @section. + * + * Returns: The #GstMpegTsBAT contained in the section, or %NULL if an error + * happened. + */ +const GstMpegTsBAT * +gst_mpegts_section_get_bat (GstMpegTsSection * section) +{ + g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_BAT, NULL); + g_return_val_if_fail (section->cached_parsed || section->data, NULL); + + if (!section->cached_parsed) + section->cached_parsed = + __common_desc_checks (section, 16, _parse_bat, + (GDestroyNotify) _gst_mpegts_bat_free); + + return (const GstMpegTsBAT *) section->cached_parsed; +} + + /* Network Information Table */ static GstMpegTsNITStream * @@ -324,7 +448,7 @@ G_DEFINE_BOXED_TYPE (GstMpegTsNIT, gst_mpegts_nit, (GBoxedCopyFunc) _gst_mpegts_nit_copy, (GFreeFunc) _gst_mpegts_nit_free); -static GstMpegTsNIT * +static gpointer _parse_nit (GstMpegTsSection * section) { GstMpegTsNIT *nit = NULL; @@ -334,13 +458,6 @@ _parse_nit (GstMpegTsSection * section) GST_DEBUG ("NIT"); - /* fixed header (no streams) + CRC == 16 */ - if (section->section_length < 16) { - GST_WARNING ("PID %d invalid NIT size %d", - section->pid, section->section_length); - goto error; - } - nit = g_slice_new0 (GstMpegTsNIT); data = section->data; @@ -429,11 +546,11 @@ _parse_nit (GstMpegTsSection * section) goto error; } - return nit; + return (gpointer) nit; error: if (nit) - gst_mpegts_section_unref (nit); + _gst_mpegts_nit_free (nit); return NULL; } @@ -453,29 +570,12 @@ gst_mpegts_section_get_nit (GstMpegTsSection * section) g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_NIT, NULL); g_return_val_if_fail (section->cached_parsed || section->data, NULL); - if (!section->cached_parsed) { - if (G_UNLIKELY (_calc_crc32 (section->data, section->section_length) != 0)) - goto bad_crc; - - section->cached_parsed = (gpointer) _parse_nit (section); - section->destroy_parsed = (GDestroyNotify) _gst_mpegts_nit_free; - if (section->cached_parsed == NULL) - goto parse_failure; - } + if (!section->cached_parsed) + section->cached_parsed = + __common_desc_checks (section, 16, _parse_nit, + (GDestroyNotify) _gst_mpegts_nit_free); return (const GstMpegTsNIT *) section->cached_parsed; - -bad_crc: - { - GST_WARNING ("Bad CRC on section"); - return NULL; - } - -parse_failure: - { - GST_WARNING ("Failure to parse section"); - return NULL; - } } @@ -517,7 +617,7 @@ G_DEFINE_BOXED_TYPE (GstMpegTsSDT, gst_mpegts_sdt, (GBoxedCopyFunc) _gst_mpegts_sdt_copy, (GFreeFunc) _gst_mpegts_sdt_free); -static GstMpegTsSDT * +static gpointer _parse_sdt (GstMpegTsSection * section) { GstMpegTsSDT *sdt = NULL; @@ -529,13 +629,6 @@ _parse_sdt (GstMpegTsSection * section) GST_DEBUG ("SDT"); - /* fixed header + CRC == 16 */ - if (section->section_length < 14) { - GST_WARNING ("PID %d invalid SDT size %d", - section->pid, section->section_length); - goto error; - } - sdt = g_slice_new0 (GstMpegTsSDT); data = section->data; @@ -564,7 +657,7 @@ _parse_sdt (GstMpegTsSection * section) entry_begin = data; - if (sdt_info_length < 9) { + if (sdt_info_length + 5 < 4) { /* each entry must be at least 5 bytes (+4 bytes for the CRC) */ GST_WARNING ("PID %d invalid SDT entry size %d", section->pid, sdt_info_length); @@ -631,37 +724,19 @@ gst_mpegts_section_get_sdt (GstMpegTsSection * section) g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_SDT, NULL); g_return_val_if_fail (section->cached_parsed || section->data, NULL); - if (!section->cached_parsed) { - if (G_UNLIKELY (_calc_crc32 (section->data, section->section_length) != 0)) - goto bad_crc; - - section->cached_parsed = (gpointer) _parse_sdt (section); - section->destroy_parsed = (GDestroyNotify) _gst_mpegts_sdt_free; - if (section->cached_parsed == NULL) - goto parse_failure; - } + if (!section->cached_parsed) + section->cached_parsed = + __common_desc_checks (section, 15, _parse_sdt, + (GDestroyNotify) _gst_mpegts_sdt_free); return (const GstMpegTsSDT *) section->cached_parsed; - -bad_crc: - { - GST_WARNING ("Bad CRC on section"); - return NULL; - } - -parse_failure: - { - GST_WARNING ("Failure to parse section"); - return NULL; - } } /* Time and Date Table (TDT) */ -static GstDateTime * +static gpointer _parse_tdt (GstMpegTsSection * section) { - /* FIXME : Add length check */ - return _parse_utc_time (section->data + 3); + return (gpointer) _parse_utc_time (section->data + 3); } /** @@ -679,20 +754,14 @@ gst_mpegts_section_get_tdt (GstMpegTsSection * section) g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_TDT, NULL); g_return_val_if_fail (section->cached_parsed || section->data, NULL); - if (!section->cached_parsed) { - section->cached_parsed = (gpointer) _parse_tdt (section); - section->destroy_parsed = (GDestroyNotify) gst_date_time_unref; - if (section->cached_parsed == NULL) - goto parse_failure; - } - - return gst_date_time_ref ((GstDateTime *) section->cached_parsed); + if (!section->cached_parsed) + section->cached_parsed = + __common_desc_checks (section, 8, _parse_tdt, + (GDestroyNotify) gst_date_time_unref); -parse_failure: - { - GST_WARNING ("Failure to parse section"); - return NULL; - } + if (section->cached_parsed) + return gst_date_time_ref ((GstDateTime *) section->cached_parsed); + return NULL; } @@ -716,15 +785,13 @@ _gst_mpegts_tot_free (GstMpegTsTOT * tot) G_DEFINE_BOXED_TYPE (GstMpegTsTOT, gst_mpegts_tot, (GBoxedCopyFunc) _gst_mpegts_tot_copy, (GFreeFunc) _gst_mpegts_tot_free); -static GstMpegTsTOT * +static gpointer _parse_tot (GstMpegTsSection * section) { guint8 *data; GstMpegTsTOT *tot; guint16 desc_len; - /* FIXME : Check minimum length */ - GST_DEBUG ("TOT"); tot = g_slice_new0 (GstMpegTsTOT); @@ -738,7 +805,7 @@ _parse_tot (GstMpegTsSection * section) data += 2; tot->descriptors = gst_mpegts_parse_descriptors (data, desc_len); - return tot; + return (gpointer) tot; } /** @@ -756,27 +823,10 @@ gst_mpegts_section_get_tot (GstMpegTsSection * section) g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_TOT, NULL); g_return_val_if_fail (section->cached_parsed || section->data, NULL); - if (!section->cached_parsed) { - if (G_UNLIKELY (_calc_crc32 (section->data, section->section_length) != 0)) - goto bad_crc; - - section->cached_parsed = (gpointer) _parse_tot (section); - section->destroy_parsed = (GDestroyNotify) _gst_mpegts_tot_free; - if (section->cached_parsed == NULL) - goto parse_failure; - } + if (!section->cached_parsed) + section->cached_parsed = + __common_desc_checks (section, 14, _parse_tot, + (GDestroyNotify) _gst_mpegts_tot_free); return (const GstMpegTsTOT *) section->cached_parsed; - -bad_crc: - { - GST_WARNING ("Bad CRC on section"); - return NULL; - } - -parse_failure: - { - GST_WARNING ("Failure to parse section"); - return NULL; - } } diff --git a/gst-libs/gst/mpegts/gst-dvb-section.h b/gst-libs/gst/mpegts/gst-dvb-section.h index af8563153..ebee4346e 100644 --- a/gst-libs/gst/mpegts/gst-dvb-section.h +++ b/gst-libs/gst/mpegts/gst-dvb-section.h @@ -171,6 +171,7 @@ typedef struct _GstMpegTsBATStream GstMpegTsBATStream; typedef struct _GstMpegTsBAT GstMpegTsBAT; #define GST_TYPE_MPEGTS_BAT (gst_mpegts_bat_get_type()) +#define GST_TYPE_MPEGTS_BAT_STREAM (gst_mpegts_bat_get_type()) struct _GstMpegTsBATStream { @@ -195,6 +196,9 @@ struct _GstMpegTsBAT }; GType gst_mpegts_bat_get_type (void); +GType gst_mpegts_bat_stream_get_type (void); + +const GstMpegTsBAT *gst_mpegts_section_get_bat (GstMpegTsSection *section); /* SDT */ #define GST_TYPE_MPEGTS_SDT (gst_mpegts_sdt_get_type()) diff --git a/gst-libs/gst/mpegts/gstmpegts-private.h b/gst-libs/gst/mpegts/gstmpegts-private.h index 917c089dc..d98c92fd3 100644 --- a/gst-libs/gst/mpegts/gstmpegts-private.h +++ b/gst-libs/gst/mpegts/gstmpegts-private.h @@ -31,4 +31,10 @@ 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); +typedef gpointer (*GstMpegTsParseFunc) (GstMpegTsSection *section); +G_GNUC_INTERNAL gpointer __common_desc_checks (GstMpegTsSection *section, + guint minsize, + GstMpegTsParseFunc parsefunc, + GDestroyNotify destroynotify); + #endif /* _GST_MPEGTS_PRIVATE_H_ */ diff --git a/gst-libs/gst/mpegts/gstmpegtssection.c b/gst-libs/gst/mpegts/gstmpegtssection.c index 508d3f7e2..1a431954e 100644 --- a/gst-libs/gst/mpegts/gstmpegtssection.c +++ b/gst-libs/gst/mpegts/gstmpegtssection.c @@ -149,6 +149,37 @@ _calc_crc32 (const guint8 * data, guint datalen) return crc; } +gpointer +__common_desc_checks (GstMpegTsSection * section, guint min_size, + GstMpegTsParseFunc parsefunc, GDestroyNotify destroynotify) +{ + gpointer res; + + /* Check section is big enough */ + if (section->section_length < min_size) { + GST_WARNING + ("PID:0x%04x table_id:0x%02x, section too small (Got %d, need at least %d)", + section->pid, section->table_id, section->section_length, min_size); + return NULL; + } + + /* If section has a CRC, check it */ + if (!section->short_section + && (_calc_crc32 (section->data, section->section_length) != 0)) { + GST_WARNING ("PID:0x%04x table_id:0x%02x, Bad CRC on section", section->pid, + section->table_id); + return NULL; + } + + /* Finally parse and set the destroy notify */ + res = parsefunc (section); + if (res == NULL) + GST_WARNING ("PID:0x%04x table_id:0x%02x, Failed to parse section", + section->pid, section->table_id); + else + section->destroy_parsed = destroynotify; + return res; +} /* @@ -287,7 +318,7 @@ gst_message_new_mpegts_section (GstObject * parent, GstMpegTsSection * section) /* Program Association Table */ -static GArray * +static gpointer _parse_pat (GstMpegTsSection * section) { GArray *pat; @@ -326,7 +357,7 @@ _parse_pat (GstMpegTsSection * section) return NULL; } - return pat; + return (gpointer) pat; } /** @@ -350,29 +381,14 @@ gst_mpegts_section_get_pat (GstMpegTsSection * section) g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_PAT, NULL); g_return_val_if_fail (section->cached_parsed || section->data, NULL); - if (!section->cached_parsed) { - if (G_UNLIKELY (_calc_crc32 (section->data, section->section_length) != 0)) - goto bad_crc; - - section->cached_parsed = (gpointer) _parse_pat (section); - section->destroy_parsed = (GDestroyNotify) g_array_unref; - if (section->cached_parsed == NULL) - goto parse_failure; - } + if (!section->cached_parsed) + section->cached_parsed = + __common_desc_checks (section, 12, _parse_pat, + (GDestroyNotify) g_array_unref); - return g_array_ref ((GArray *) section->cached_parsed); - -bad_crc: - { - GST_WARNING ("Bad CRC on section"); - return NULL; - } - -parse_failure: - { - GST_WARNING ("Failure to parse section"); - return NULL; - } + if (section->cached_parsed) + return g_array_ref ((GArray *) section->cached_parsed); + return NULL; } @@ -415,7 +431,7 @@ G_DEFINE_BOXED_TYPE (GstMpegTsPMT, gst_mpegts_pmt, (GBoxedCopyFunc) _gst_mpegts_pmt_copy, (GFreeFunc) _gst_mpegts_pmt_free); -static GstMpegTsPMT * +static gpointer _parse_pmt (GstMpegTsSection * section) { GstMpegTsPMT *pmt = NULL; @@ -424,13 +440,6 @@ _parse_pmt (GstMpegTsSection * section) guint program_info_length; guint stream_info_length; - /* fixed header + CRC == 16 */ - if (section->section_length < 16) { - GST_WARNING ("PID %d invalid PMT size %d", - section->pid, section->section_length); - goto error; - } - pmt = g_slice_new0 (GstMpegTsPMT); data = section->data; @@ -496,11 +505,11 @@ _parse_pmt (GstMpegTsSection * section) g_assert (data == end - 4); - return pmt; + return (gpointer) pmt; error: if (pmt) - gst_mpegts_section_unref (pmt); + _gst_mpegts_pmt_free (pmt); return NULL; } @@ -520,34 +529,17 @@ gst_mpegts_section_get_pmt (GstMpegTsSection * section) g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_PMT, NULL); g_return_val_if_fail (section->cached_parsed || section->data, NULL); - if (!section->cached_parsed) { - if (G_UNLIKELY (_calc_crc32 (section->data, section->section_length) != 0)) - goto bad_crc; - - section->cached_parsed = (gpointer) _parse_pmt (section); - section->destroy_parsed = (GDestroyNotify) _gst_mpegts_pmt_free; - if (section->cached_parsed == NULL) - goto parse_failure; - } + if (!section->cached_parsed) + section->cached_parsed = + __common_desc_checks (section, 16, _parse_pmt, + (GDestroyNotify) _gst_mpegts_pmt_free); return (const GstMpegTsPMT *) section->cached_parsed; - -bad_crc: - { - GST_WARNING ("Bad CRC on section"); - return NULL; - } - -parse_failure: - { - GST_WARNING ("Failure to parse section"); - return NULL; - } } /* Conditional Access Table */ -static GArray * +static gpointer _parse_cat (GstMpegTsSection * section) { guint8 *data; @@ -558,7 +550,7 @@ _parse_cat (GstMpegTsSection * section) /* descriptors */ desc_len = section->section_length - 4 - 8; - return gst_mpegts_parse_descriptors (data, desc_len); + return (gpointer) gst_mpegts_parse_descriptors (data, desc_len); } /** @@ -578,20 +570,14 @@ gst_mpegts_section_get_cat (GstMpegTsSection * section) g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_CAT, NULL); g_return_val_if_fail (section->cached_parsed || section->data, NULL); - if (!section->cached_parsed) { - section->cached_parsed = (gpointer) _parse_cat (section); - section->destroy_parsed = (GDestroyNotify) g_array_unref; - if (section->cached_parsed == NULL) - goto parse_failure; - } - - return g_array_ref ((GArray *) section->cached_parsed); + if (!section->cached_parsed) + section->cached_parsed = + __common_desc_checks (section, 12, _parse_cat, + (GDestroyNotify) g_array_unref); -parse_failure: - { - GST_WARNING ("Failure to parse section"); - return NULL; - } + if (section->cached_parsed) + return g_array_ref ((GArray *) section->cached_parsed); + return NULL; } /* Transport Stream Description Table (TSDT) */ @@ -662,11 +648,15 @@ _identify_section (guint16 pid, guint8 table_id) return GST_MPEGTS_SECTION_PAT; break; case GST_MTS_TABLE_ID_CONDITIONAL_ACCESS: - return GST_MPEGTS_SECTION_CAT; + if (pid == 0x01) + return GST_MPEGTS_SECTION_CAT; + break; case GST_MTS_TABLE_ID_TS_PROGRAM_MAP: return GST_MPEGTS_SECTION_PMT; case GST_MTS_TABLE_ID_BOUQUET_ASSOCIATION: - return GST_MPEGTS_SECTION_BAT; + if (pid == 0x0011) + return GST_MPEGTS_SECTION_BAT; + break; case GST_MTS_TABLE_ID_NETWORK_INFORMATION_ACTUAL_NETWORK: case GST_MTS_TABLE_ID_NETWORK_INFORMATION_OTHER_NETWORK: if (pid == 0x0010) |