From e701517a31e8c19aaf4ce53bd50f660f98a30277 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Sat, 5 Jul 2008 15:56:56 +0000 Subject: [PATCH] gst/mpegstream/: Resend tags event after a FLUSH (seek) to support prerolling a partial pipeline. Original commit message from CVS: * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_base_init), (gst_dvd_demux_get_audio_stream), (gst_dvd_demux_get_subpicture_stream), (gst_dvd_demux_parse_packhead), (gst_dvd_demux_reset): * gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_init), (gst_mpeg_demux_process_event), (gst_mpeg_demux_init_stream), (gst_mpeg_demux_parse_packhead), (gst_mpeg_demux_reset): * gst/mpegstream/gstmpegdemux.h: Resend tags event after a FLUSH (seek) to support prerolling a partial pipeline. --- ChangeLog | 13 +++++++++++++ gst/mpegstream/gstdvddemux.c | 32 ++++++++++++++++++++++++++++++++ gst/mpegstream/gstmpegdemux.c | 22 ++++++++++++++++++++++ gst/mpegstream/gstmpegdemux.h | 2 ++ 4 files changed, 69 insertions(+) diff --git a/ChangeLog b/ChangeLog index dbcffd64a4..acd900cd10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-07-05 Mark Nauwelaerts + + * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_base_init), + (gst_dvd_demux_get_audio_stream), + (gst_dvd_demux_get_subpicture_stream), + (gst_dvd_demux_parse_packhead), (gst_dvd_demux_reset): + * gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_init), + (gst_mpeg_demux_process_event), (gst_mpeg_demux_init_stream), + (gst_mpeg_demux_parse_packhead), (gst_mpeg_demux_reset): + * gst/mpegstream/gstmpegdemux.h: + Resend tags event after a FLUSH (seek) to support prerolling + a partial pipeline. + 2008-07-03 Tim-Philipp Müller * configure.ac: diff --git a/gst/mpegstream/gstdvddemux.c b/gst/mpegstream/gstdvddemux.c index f2de7b38e4..f0619a8b3b 100644 --- a/gst/mpegstream/gstdvddemux.c +++ b/gst/mpegstream/gstdvddemux.c @@ -141,6 +141,8 @@ static void gst_dvd_demux_init (GstDVDDemux * dvd_demux, static gboolean gst_dvd_demux_process_event (GstMPEGParse * mpeg_parse, GstEvent * event); +static gboolean gst_dvd_demux_parse_packhead (GstMPEGParse * mpeg_parse, + GstBuffer * buffer); static gboolean gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event); @@ -195,6 +197,7 @@ gst_dvd_demux_base_init (gpointer klass) mpeg_parse_class->send_buffer = NULL; mpeg_parse_class->process_event = gst_dvd_demux_process_event; + mpeg_parse_class->parse_packhead = gst_dvd_demux_parse_packhead; /* sink pad */ gst_element_class_add_pad_template (element_class, @@ -669,6 +672,7 @@ gst_dvd_demux_get_audio_stream (GstMPEGDemux * mpeg_demux, gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_LANGUAGE_CODE, lang_code, NULL); } + str->tags = gst_tag_list_copy (list); gst_element_found_tags_for_pad (GST_ELEMENT (mpeg_demux), str->pad, list); } @@ -758,6 +762,7 @@ gst_dvd_demux_get_subpicture_stream (GstMPEGDemux * mpeg_demux, gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_LANGUAGE_CODE, lang_code, NULL); + str->tags = gst_tag_list_copy (list); gst_element_found_tags_for_pad (GST_ELEMENT (mpeg_demux), str->pad, list); } @@ -768,6 +773,31 @@ gst_dvd_demux_get_subpicture_stream (GstMPEGDemux * mpeg_demux, return str; } +static gboolean +gst_dvd_demux_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer) +{ + GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (mpeg_parse); + GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_parse); + gboolean pending_tags = mpeg_demux->pending_tags; + + GST_MPEG_PARSE_CLASS (parent_class)->parse_packhead (mpeg_parse, buffer); + + if (pending_tags) { + GstMPEGStream **streams; + guint i, num; + + streams = dvd_demux->subpicture_stream; + num = GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS; + for (i = 0; i < num; ++i) { + if (streams[i] != NULL && streams[i]->tags != NULL) + gst_pad_push_event (streams[i]->pad, + gst_event_new_tag (gst_tag_list_copy (streams[i]->tags))); + } + } + + return TRUE; +} + static GstFlowReturn gst_dvd_demux_process_private (GstMPEGDemux * mpeg_demux, GstBuffer * buffer, @@ -1134,6 +1164,8 @@ gst_dvd_demux_reset (GstDVDDemux * dvd_demux) gst_element_remove_pad (GST_ELEMENT (dvd_demux), dvd_demux->subpicture_stream[i]->pad); + if (dvd_demux->subpicture_stream[i]->tags) + gst_tag_list_free (dvd_demux->subpicture_stream[i]->tags); g_free (dvd_demux->subpicture_stream[i]); dvd_demux->subpicture_stream[i] = NULL; } diff --git a/gst/mpegstream/gstmpegdemux.c b/gst/mpegstream/gstmpegdemux.c index ccabdaa5c9..dbbd02ac05 100644 --- a/gst/mpegstream/gstmpegdemux.c +++ b/gst/mpegstream/gstmpegdemux.c @@ -231,6 +231,7 @@ gst_mpeg_demux_init (GstMPEGDemux * mpeg_demux, GstMPEGDemuxClass * klass) mpeg_demux->max_gap_tolerance = GST_CLOCK_TIME_NONE; mpeg_demux->last_pts = -1; + mpeg_demux->pending_tags = FALSE; } @@ -245,6 +246,8 @@ gst_mpeg_demux_process_event (GstMPEGParse * mpeg_parse, GstEvent * event) ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse, event); + demux->pending_tags = TRUE; + gst_mpeg_streams_reset_last_flow (demux->video_stream, GST_MPEG_DEMUX_NUM_VIDEO_STREAMS); gst_mpeg_streams_reset_last_flow (demux->audio_stream, @@ -327,6 +330,7 @@ gst_mpeg_demux_init_stream (GstMPEGDemux * mpeg_demux, str->last_flow = GST_FLOW_OK; str->buffers_sent = 0; + str->tags = NULL; } static GstMPEGStream * @@ -493,6 +497,7 @@ gst_mpeg_demux_get_private_stream (GstMPEGDemux * mpeg_demux, static gboolean gst_mpeg_demux_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer) { + GstMPEGDemux *demux = GST_MPEG_DEMUX (mpeg_parse); guint8 *buf; parent_class->parse_packhead (mpeg_parse, buffer); @@ -500,6 +505,20 @@ gst_mpeg_demux_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer) buf = GST_BUFFER_DATA (buffer); /* do something useful here */ + if (demux->pending_tags) { + GstMPEGStream **streams; + guint i, num; + + streams = demux->audio_stream; + num = GST_MPEG_DEMUX_NUM_AUDIO_STREAMS; + for (i = 0; i < num; ++i) { + if (streams[i] != NULL && streams[i]->tags != NULL) + gst_pad_push_event (streams[i]->pad, + gst_event_new_tag (gst_tag_list_copy (streams[i]->tags))); + } + demux->pending_tags = FALSE; + } + return TRUE; } @@ -1323,6 +1342,8 @@ gst_mpeg_demux_reset (GstMPEGDemux * mpeg_demux) gst_event_new_eos ()); gst_element_remove_pad (GST_ELEMENT (mpeg_demux), mpeg_demux->audio_stream[i]->pad); + if (mpeg_demux->audio_stream[i]->tags) + gst_tag_list_free (mpeg_demux->audio_stream[i]->tags); g_free (mpeg_demux->audio_stream[i]); mpeg_demux->audio_stream[i] = NULL; } @@ -1351,6 +1372,7 @@ gst_mpeg_demux_reset (GstMPEGDemux * mpeg_demux) mpeg_demux->index = NULL; mpeg_demux->last_pts = -1; + mpeg_demux->pending_tags = FALSE; /* * Don't adjust things that are only for subclass use diff --git a/gst/mpegstream/gstmpegdemux.h b/gst/mpegstream/gstmpegdemux.h index a2a56fd4bf..583de0d2f4 100644 --- a/gst/mpegstream/gstmpegdemux.h +++ b/gst/mpegstream/gstmpegdemux.h @@ -98,6 +98,7 @@ struct _GstMPEGStream { GstClockTimeDiff scr_offs; GstFlowReturn last_flow; guint buffers_sent; + GstTagList *tags; }; /* Extended structure to hold additional information for video @@ -126,6 +127,7 @@ struct _GstMPEGDemux { gint64 total_size_bound; gint64 last_pts; + gboolean pending_tags; GstIndex *index; /* stream output */