From 26b37c7acb38bdf517d4917fcee1180339339056 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 3 Jun 2016 10:36:32 +0300 Subject: [PATCH] dvdemux: Remember if upstream had a time segment and if not properly create time segments Previously the segment.time was wrong, and the position was not updated correctly, resulting in seeks in PUSH mode with upstream providing a BYTES segment to not work at all. https://bugzilla.gnome.org/show_bug.cgi?id=767157 --- ext/dv/gstdvdemux.c | 22 ++++++++++++++++++++-- ext/dv/gstdvdemux.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/ext/dv/gstdvdemux.c b/ext/dv/gstdvdemux.c index 3ac61b7..e02a006 100644 --- a/ext/dv/gstdvdemux.c +++ b/ext/dv/gstdvdemux.c @@ -268,6 +268,7 @@ gst_dvdemux_reset (GstDVDemux * dvdemux) dvdemux->wide = FALSE; gst_segment_init (&dvdemux->byte_segment, GST_FORMAT_BYTES); gst_segment_init (&dvdemux->time_segment, GST_FORMAT_TIME); + dvdemux->upstream_time_segment = FALSE; dvdemux->have_group_id = FALSE; dvdemux->group_id = G_MAXUINT; } @@ -797,6 +798,8 @@ gst_dvdemux_handle_sink_event (GstPad * pad, GstObject * parent, case GST_FORMAT_TIME: gst_segment_copy_into (segment, &dvdemux->time_segment); + dvdemux->upstream_time_segment = TRUE; + /* and we can just forward this time event */ res = gst_dvdemux_push_event (dvdemux, event); break; @@ -1484,9 +1487,11 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, GstBuffer * buffer) GstSMPTETimeCode timecode; int frame_number; - if (G_UNLIKELY (dvdemux->need_segment)) { + if (dvdemux->need_segment) { GstFormat format; + g_assert (!dvdemux->upstream_time_segment); + /* convert to time and store as start/end_timestamp */ format = GST_FORMAT_TIME; if (!(gst_dvdemux_convert_sink_pair (dvdemux, @@ -1496,8 +1501,12 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, GstBuffer * buffer) (gint64 *) & dvdemux->time_segment.stop))) goto segment_error; + dvdemux->time_segment.time = dvdemux->time_segment.start; dvdemux->time_segment.rate = dvdemux->byte_segment.rate; - dvdemux->time_segment.position = dvdemux->time_segment.start; + + gst_dvdemux_sink_convert (dvdemux, + GST_FORMAT_BYTES, dvdemux->byte_segment.position, + GST_FORMAT_TIME, (gint64 *) & dvdemux->time_segment.position); gst_dvdemux_update_frame_offsets (dvdemux, dvdemux->time_segment.position); @@ -1652,6 +1661,10 @@ gst_dvdemux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { gst_adapter_clear (dvdemux->adapter); dvdemux->discont = TRUE; + + /* Should recheck where we are */ + if (!dvdemux->upstream_time_segment) + dvdemux->need_segment = TRUE; } /* a timestamp always should be respected */ @@ -1662,6 +1675,11 @@ gst_dvdemux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) if (dvdemux->discont) gst_dvdemux_update_frame_offsets (dvdemux, dvdemux->time_segment.position); + } else if (dvdemux->upstream_time_segment && dvdemux->discont) { + /* This will probably fail later to provide correct + * timestamps and/or durations but also should not happen */ + GST_ERROR_OBJECT (dvdemux, + "Upstream provides TIME segment but no PTS after discont"); } gst_adapter_push (dvdemux->adapter, buffer); diff --git a/ext/dv/gstdvdemux.h b/ext/dv/gstdvdemux.h index 4f69433..be1d783 100644 --- a/ext/dv/gstdvdemux.h +++ b/ext/dv/gstdvdemux.h @@ -76,6 +76,7 @@ struct _GstDVDemux { GstDVDemuxSeekHandler seek_handler; GstSegment byte_segment; + gboolean upstream_time_segment; GstSegment time_segment; gboolean need_segment; gboolean new_media; -- 2.7.4