From 13431420ebbf52cbfc6245e875db78b4fbd3c2ca Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20P=C3=B6lsterl?= Date: Thu, 28 Oct 2010 11:43:34 +0100 Subject: [PATCH] mpegtsparse: Add tag event emission. Fixes #627253 --- gst/mpegdemux/mpegtsparse.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/gst/mpegdemux/mpegtsparse.c b/gst/mpegdemux/mpegtsparse.c index b879e23..579b755 100644 --- a/gst/mpegdemux/mpegtsparse.c +++ b/gst/mpegdemux/mpegtsparse.c @@ -35,6 +35,7 @@ #define TS_LATENCY 700 #define TABLE_ID_UNSET 0xFF +#define RUNNING_STATUS_RUNNING 4 GST_DEBUG_CATEGORY_STATIC (mpegts_parse_debug); #define GST_CAT_DEFAULT mpegts_parse_debug @@ -73,6 +74,9 @@ struct _MpegTSParsePad /* the return of the latest push */ GstFlowReturn flow_return; + + GstTagList *tags; + guint event_id; }; static GQuark QUARK_PROGRAMS; @@ -135,6 +139,10 @@ static GstStateChangeReturn mpegts_parse_change_state (GstElement * element, GstStateChange transition); static gboolean mpegts_parse_src_pad_query (GstPad * pad, GstQuery * query); static void _extra_init (GType type); +static void mpegts_parse_get_tags_from_sdt (MpegTSParse * parse, + GstStructure * sdt_info); +static void mpegts_parse_get_tags_from_eit (MpegTSParse * parse, + GstStructure * eit_info); GST_BOILERPLATE_FULL (MpegTSParse, mpegts_parse, GstElement, GST_TYPE_ELEMENT, _extra_init); @@ -623,6 +631,10 @@ mpegts_parse_create_tspad (MpegTSParse * parse, const gchar * pad_name) static void mpegts_parse_destroy_tspad (MpegTSParse * parse, MpegTSParsePad * tspad) { + if (tspad->tags) { + gst_tag_list_free (tspad->tags); + } + /* free the wrapper */ g_free (tspad); } @@ -725,6 +737,12 @@ mpegts_parse_tspad_push (MpegTSParse * parse, MpegTSParsePad * tspad, if (tspad->program_number != -1) { if (tspad->program) { pad_pids = tspad->program->streams; + + if (tspad->tags) { + gst_element_found_tags_for_pad (GST_ELEMENT_CAST (parse), + tspad->pad, tspad->tags); + tspad->tags = NULL; + } } else { /* there's a program filter on the pad but the PMT for the program has not * been parsed yet, ignore the pad until we get a PMT */ @@ -1080,6 +1098,8 @@ static void mpegts_parse_apply_sdt (MpegTSParse * parse, guint16 pmt_pid, GstStructure * sdt_info) { + mpegts_parse_get_tags_from_sdt (parse, sdt_info); + gst_element_post_message (GST_ELEMENT_CAST (parse), gst_message_new_element (GST_OBJECT (parse), gst_structure_copy (sdt_info))); @@ -1089,6 +1109,8 @@ static void mpegts_parse_apply_eit (MpegTSParse * parse, guint16 pmt_pid, GstStructure * eit_info) { + mpegts_parse_get_tags_from_eit (parse, eit_info); + gst_element_post_message (GST_ELEMENT_CAST (parse), gst_message_new_element (GST_OBJECT (parse), gst_structure_copy (eit_info))); @@ -1215,6 +1237,81 @@ mpegts_parse_handle_psi (MpegTSParse * parse, MpegTSPacketizerSection * section) return res; } +static void +mpegts_parse_get_tags_from_sdt (MpegTSParse * parse, GstStructure * sdt_info) +{ + const GValue *services; + guint i; + + services = gst_structure_get_value (sdt_info, "services"); + + for (i = 0; i < gst_value_list_get_size (services); i++) { + const GstStructure *service; + const gchar *sid_str; + gchar *tmp; + gint program_number; + MpegTSParseProgram *program; + + service = gst_value_get_structure (gst_value_list_get_value (services, i)); + + /* get program_number from structure name + * which looks like service-%d */ + sid_str = gst_structure_get_name (service); + tmp = g_strstr_len (sid_str, -1, "-"); + if (tmp) { + program_number = atoi (++tmp); + } + + program = mpegts_parse_get_program (parse, program_number); + if (program && program->tspad && !program->tspad->tags) { + program->tspad->tags = gst_tag_list_new_full (GST_TAG_ARTIST, + gst_structure_get_string (service, "name"), NULL); + } + } +} + +static void +mpegts_parse_get_tags_from_eit (MpegTSParse * parse, GstStructure * eit_info) +{ + const GValue *events; + guint i; + guint program_number; + MpegTSParseProgram *program; + gboolean present_following; + + gst_structure_get_uint (eit_info, "service-id", &program_number); + program = mpegts_parse_get_program (parse, program_number); + + gst_structure_get_boolean (eit_info, "present-following", &present_following); + + if (program && program->tspad && present_following) { + events = gst_structure_get_value (eit_info, "events"); + + for (i = 0; i < gst_value_list_get_size (events); i++) { + const GstStructure *event; + const gchar *title; + guint status; + guint event_id; + guint duration; + + event = gst_value_get_structure (gst_value_list_get_value (events, i)); + + title = gst_structure_get_string (event, "name"); + gst_structure_get_uint (event, "event-id", &event_id); + gst_structure_get_uint (event, "running-status", &status); + + if (title && event_id != program->tspad->event_id + && status == RUNNING_STATUS_RUNNING) { + gst_structure_get_uint (event, "duration", &duration); + + program->tspad->event_id = event_id; + program->tspad->tags = gst_tag_list_new_full (GST_TAG_TITLE, + title, GST_TAG_DURATION, duration * GST_SECOND, NULL); + } + } + } +} + static gboolean mpegts_parse_sink_event (GstPad * pad, GstEvent * event) { -- 2.7.4