diff --git a/ChangeLog b/ChangeLog index 8377a3a8fe..5e27a4543d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-04-29 Zaheer Abbas Merali + + * gst/mpegtsparse/mpegtspacketizer.c: + * gst/mpegtsparse/mpegtspacketizer.h: + * gst/mpegtsparse/mpegtsparse.c: + Detect SI pids (NIT, SDT, EIT etc.) based on table id and not + by pid number. This allows for example the EPG data from UK's + freesat to be picked up. + 2008-04-26 Sebastian Dröge * ext/mpeg2enc/gstmpeg2enc.cc: diff --git a/gst/mpegtsparse/mpegtspacketizer.c b/gst/mpegtsparse/mpegtspacketizer.c index 526a25dfda..57dd84523b 100644 --- a/gst/mpegtsparse/mpegtspacketizer.c +++ b/gst/mpegtsparse/mpegtspacketizer.c @@ -34,25 +34,8 @@ static void mpegts_packetizer_finalize (GObject * object); #define CONTINUITY_UNSET 255 #define MAX_CONTINUITY 15 -#define VERSION_NUMBER_NOTSET 255 - -typedef struct -{ - guint8 table_id; - /* the spec says sub_table_extension is the fourth and fifth byte of a - * section when the section_syntax_indicator is set to a value of "1". If - * section_syntax_indicator is 0, sub_table_extension will be set to 0 */ - guint16 subtable_extension; - guint8 version_number; -} MpegTSPacketizerStreamSubtable; - -typedef struct -{ - guint continuity_counter; - GstAdapter *section_adapter; - guint section_length; - GSList *subtables; -} MpegTSPacketizerStream; +#define VERSION_NUMBER_UNSET 255 +#define TABLE_ID_UNSET 0xFF static gint mpegts_packetizer_stream_subtable_compare (gconstpointer a, gconstpointer b) @@ -75,7 +58,7 @@ mpegts_packetizer_stream_subtable_new (guint8 table_id, MpegTSPacketizerStreamSubtable *subtable; subtable = g_new0 (MpegTSPacketizerStreamSubtable, 1); - subtable->version_number = VERSION_NUMBER_NOTSET; + subtable->version_number = VERSION_NUMBER_UNSET; subtable->table_id = table_id; subtable->subtable_extension = subtable_extension; return subtable; @@ -90,6 +73,7 @@ mpegts_packetizer_stream_new () stream->section_adapter = gst_adapter_new (); stream->continuity_counter = CONTINUITY_UNSET; stream->subtables = NULL; + stream->section_table_id = TABLE_ID_UNSET; return stream; } @@ -110,6 +94,7 @@ mpegts_packetizer_clear_section (MpegTSPacketizer * packetizer, gst_adapter_clear (stream->section_adapter); stream->continuity_counter = CONTINUITY_UNSET; stream->section_length = 0; + stream->section_table_id = TABLE_ID_UNSET; } static void @@ -282,6 +267,7 @@ mpegts_packetizer_parse_section_header (MpegTSPacketizer * packetizer, if (section->version_number == subtable->version_number) goto not_applicable; subtable->version_number = section->version_number; + stream->section_table_id = section->table_id; return TRUE; @@ -1887,6 +1873,7 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer, } stream->continuity_counter = packet->continuity_counter; stream->section_length = section_length; + stream->section_table_id = table_id; gst_adapter_push (stream->section_adapter, sub_buf); res = TRUE; diff --git a/gst/mpegtsparse/mpegtspacketizer.h b/gst/mpegtsparse/mpegtspacketizer.h index f156ce5f3b..c54228afa9 100644 --- a/gst/mpegtsparse/mpegtspacketizer.h +++ b/gst/mpegtsparse/mpegtspacketizer.h @@ -85,6 +85,26 @@ typedef struct guint8 current_next_indicator; } MpegTSPacketizerSection; +typedef struct +{ + guint8 table_id; + /* the spec says sub_table_extension is the fourth and fifth byte of a + * section when the section_syntax_indicator is set to a value of "1". If + * section_syntax_indicator is 0, sub_table_extension will be set to 0 */ + guint16 subtable_extension; + guint8 version_number; +} MpegTSPacketizerStreamSubtable; + +typedef struct +{ + guint continuity_counter; + GstAdapter *section_adapter; + guint8 section_table_id; + guint section_length; + GSList *subtables; +} MpegTSPacketizerStream; + + GType gst_mpegts_packetizer_get_type(void); void mpegts_packetizer_init_debug (); diff --git a/gst/mpegtsparse/mpegtsparse.c b/gst/mpegtsparse/mpegtsparse.c index d047f36ae3..77f65f00c4 100644 --- a/gst/mpegtsparse/mpegtsparse.c +++ b/gst/mpegtsparse/mpegtsparse.c @@ -33,6 +33,8 @@ /* latency in mseconds */ #define TS_LATENCY 700 +#define TABLE_ID_UNSET 0xFF + GST_DEBUG_CATEGORY_STATIC (mpegts_parse_debug); #define GST_CAT_DEFAULT mpegts_parse_debug @@ -247,18 +249,6 @@ mpegts_parse_reset (MpegTSParse * parse) g_hash_table_insert (parse->psi_pids, GINT_TO_POINTER (0), GINT_TO_POINTER (1)); - /* NIT */ - g_hash_table_insert (parse->psi_pids, - GINT_TO_POINTER (0x10), GINT_TO_POINTER (1)); - - /* SDT */ - g_hash_table_insert (parse->psi_pids, - GINT_TO_POINTER (0x11), GINT_TO_POINTER (1)); - - /* EIT */ - g_hash_table_insert (parse->psi_pids, - GINT_TO_POINTER (0x12), GINT_TO_POINTER (1)); - /* pmt pids will be added and removed dynamically */ } @@ -790,10 +780,53 @@ mpegts_parse_push (MpegTSParse * parse, MpegTSPacketizerPacket * packet, } static gboolean -mpegts_parse_is_psi_pid (MpegTSParse * parse, guint16 pid) +mpegts_parse_is_psi (MpegTSParse * parse, MpegTSPacketizerPacket * packet) { - return g_hash_table_lookup (parse->psi_pids, - GINT_TO_POINTER ((gint) pid)) != NULL; + gboolean retval = FALSE; + guint8 table_id; + int i; + guint8 si_tables[] = { 0x00, 0x01, 0x02, 0x03, 0x40, 0x41, 0x42, 0x46, 0x4A, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, + 0x72, 0x73, 0x7E, 0x7F, TABLE_ID_UNSET + }; + if (g_hash_table_lookup (parse->psi_pids, + GINT_TO_POINTER ((gint) packet->pid)) != NULL) + retval = TRUE; + if (!retval) { + if (packet->payload_unit_start_indicator) { + table_id = *(packet->data); + i = 0; + while (si_tables[i] != TABLE_ID_UNSET) { + if (si_tables[i] == table_id) { + retval = TRUE; + break; + } + i++; + } + } else { + MpegTSPacketizerStream *stream = (MpegTSPacketizerStream *) + g_hash_table_lookup (parse->packetizer->streams, + GINT_TO_POINTER ((gint) packet->pid)); + + if (stream) { + i = 0; + GST_DEBUG_OBJECT (parse, "section table id: 0x%x", + stream->section_table_id); + while (si_tables[i] != TABLE_ID_UNSET) { + if (si_tables[i] == stream->section_table_id) { + retval = TRUE; + break; + } + i++; + } + } + } + } + GST_DEBUG_OBJECT (parse, "Packet of pid 0x%x is psi: %d", packet->pid, + retval); + return retval; } static void @@ -1152,7 +1185,7 @@ mpegts_parse_chain (GstPad * pad, GstBuffer * buf) goto next; /* parse PSI data */ - if (packet.payload != NULL && mpegts_parse_is_psi_pid (parse, packet.pid)) { + if (packet.payload != NULL && mpegts_parse_is_psi (parse, &packet)) { MpegTSPacketizerSection section; parsed = mpegts_packetizer_push_section (packetizer, &packet, §ion);