From 720c3525de5305f6429191f1b432875ff698a10f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 6 Sep 2016 14:25:42 +0300 Subject: [PATCH] dvdemux: Fix timestamping in reverse playback mode This is only supported right now if after a demuxer that supports reverse playback, e.g. with DV container inside AVI container. --- ext/dv/gstdvdemux.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/ext/dv/gstdvdemux.c b/ext/dv/gstdvdemux.c index 06e9297..6040270 100644 --- a/ext/dv/gstdvdemux.c +++ b/ext/dv/gstdvdemux.c @@ -1533,10 +1533,18 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, GstBuffer * buffer) GST_SMPTE_TIME_CODE_SYSTEM_25 : GST_SMPTE_TIME_CODE_SYSTEM_30, &frame_number, &timecode); - next_ts = gst_util_uint64_scale_int ( - (dvdemux->frame_offset + 1) * GST_SECOND, - dvdemux->framerate_denominator, dvdemux->framerate_numerator); - duration = next_ts - dvdemux->time_segment.position; + if (dvdemux->time_segment.rate < 0) { + next_ts = gst_util_uint64_scale_int ( + (dvdemux->frame_offset > + 0 ? dvdemux->frame_offset - 1 : 0) * GST_SECOND, + dvdemux->framerate_denominator, dvdemux->framerate_numerator); + duration = dvdemux->time_segment.position - next_ts; + } else { + next_ts = gst_util_uint64_scale_int ( + (dvdemux->frame_offset + 1) * GST_SECOND, + dvdemux->framerate_denominator, dvdemux->framerate_numerator); + duration = next_ts - dvdemux->time_segment.position; + } gst_buffer_map (buffer, &map, GST_MAP_READ); dv_parse_packs (dvdemux->decoder, map.data); @@ -1569,10 +1577,22 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, GstBuffer * buffer) dvdemux->discont = FALSE; dvdemux->time_segment.position = next_ts; - dvdemux->frame_offset++; + + if (dvdemux->time_segment.rate < 0) { + if (dvdemux->frame_offset > 0) + dvdemux->frame_offset--; + else + GST_WARNING_OBJECT (dvdemux, + "Got before frame offset 0 in reverse playback"); + } else { + dvdemux->frame_offset++; + } /* check for the end of the segment */ - if (dvdemux->time_segment.stop != -1 && next_ts > dvdemux->time_segment.stop) + if ((dvdemux->time_segment.rate > 0 && dvdemux->time_segment.stop != -1 + && next_ts > dvdemux->time_segment.stop) + || (dvdemux->time_segment.rate < 0 + && dvdemux->time_segment.start > next_ts)) ret = GST_FLOW_EOS; else ret = GST_FLOW_OK; -- 2.7.4