From: Carl Hetherington Date: Thu, 8 Dec 2016 11:23:58 +0000 (+0000) Subject: Further fixes and tidying to 'better-seek'. X-Git-Tag: v2.10.3-test~9^2~1 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;ds=sidebyside;h=a28ef704adf8c5bfa45b3d6285f741af64758ceb;p=dcpomatic.git Further fixes and tidying to 'better-seek'. This fixes the failure to keep track of the `position' of each stream of a multi-stream file. It also tidies things up a bit. --- diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index fd0835596..1b1ae70c0 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -32,6 +32,7 @@ using std::cout; using std::map; using boost::shared_ptr; +using boost::optional; AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr content, shared_ptr log) : DecoderPart (parent, log) @@ -83,7 +84,7 @@ AudioDecoder::give (AudioStreamPtr stream, shared_ptr data, void AudioDecoder::flush () { - for (map >::const_iterator i = _streams.begin(); i != _streams.end(); ++i) { + for (StreamMap::const_iterator i = _streams.begin(); i != _streams.end(); ++i) { i->second->flush (); } } @@ -92,7 +93,7 @@ void AudioDecoder::seek (ContentTime t, bool accurate) { _log->log (String::compose ("AD seek to %1", to_string(t)), LogEntry::TYPE_DEBUG_DECODE); - for (map >::const_iterator i = _streams.begin(); i != _streams.end(); ++i) { + for (StreamMap::const_iterator i = _streams.begin(); i != _streams.end(); ++i) { i->second->seek (t, accurate); } } @@ -100,7 +101,19 @@ AudioDecoder::seek (ContentTime t, bool accurate) void AudioDecoder::set_fast () { - for (map >::const_iterator i = _streams.begin(); i != _streams.end(); ++i) { + for (StreamMap::const_iterator i = _streams.begin(); i != _streams.end(); ++i) { i->second->set_fast (); } } + +optional +AudioDecoder::position () const +{ + optional pos; + for (StreamMap::const_iterator i = _streams.begin(); i != _streams.end(); ++i) { + if (!pos || (i->second->position() && i->second->position().get() < pos.get())) { + pos = i->second->position(); + } + } + return pos; +} diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 4b7594f35..cdb643cee 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -58,9 +58,12 @@ public: void flush (); void seek (ContentTime t, bool accurate); + boost::optional position () const; + private: /** An AudioDecoderStream object to manage each stream in _audio_content */ - std::map > _streams; + typedef std::map > StreamMap; + StreamMap _streams; }; #endif diff --git a/src/lib/audio_decoder_stream.cc b/src/lib/audio_decoder_stream.cc index af46593ab..a82ebc4cf 100644 --- a/src/lib/audio_decoder_stream.cc +++ b/src/lib/audio_decoder_stream.cc @@ -272,3 +272,13 @@ AudioDecoderStream::set_fast () _resampler->set_fast (); } } + +optional +AudioDecoderStream::position () const +{ + if (!_position) { + return optional (); + } + + return ContentTime::from_frames (_position.get(), _content->resampled_frame_rate()); +} diff --git a/src/lib/audio_decoder_stream.h b/src/lib/audio_decoder_stream.h index 78747bfc5..9ec5c5a09 100644 --- a/src/lib/audio_decoder_stream.h +++ b/src/lib/audio_decoder_stream.h @@ -43,6 +43,8 @@ public: void seek (ContentTime time, bool accurate); void set_fast (); + boost::optional position () const; + private: void reset_decoded (); diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index e384e1230..b7397099c 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -164,9 +164,6 @@ DCPDecoder::pass (PassReason reason, bool) } } - video->set_position (_next); - audio->set_position (_next); - subtitle->set_position (_next); _next += ContentTime::from_frames (1, vfr); if ((*_reel)->main_picture ()) { diff --git a/src/lib/dcp_subtitle_decoder.cc b/src/lib/dcp_subtitle_decoder.cc index daafee3e5..824ddba19 100644 --- a/src/lib/dcp_subtitle_decoder.cc +++ b/src/lib/dcp_subtitle_decoder.cc @@ -80,7 +80,6 @@ DCPSubtitleDecoder::pass (PassReason, bool) } subtitle->give_text (p, s); - subtitle->set_position (p.from); return false; } diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index b7bd78c14..e538a51d4 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -19,19 +19,19 @@ */ #include "decoder.h" +#include "decoder_part.h" #include using std::cout; using boost::optional; void -Decoder::maybe_seek (optional& position, ContentTime time, bool accurate) +Decoder::maybe_seek (opional position, ContentTime time, bool accurate) { - if (position && (time >= *position && time < (*position + ContentTime::from_seconds(1)))) { + if (position && (time >= position.get() && time < (position.get() + ContentTime::from_seconds(1)))) { /* No need to seek: caller should just pass() */ return; } - position.reset (); seek (time, accurate); } diff --git a/src/lib/decoder.h b/src/lib/decoder.h index bd4bf01c2..3717d931d 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -33,6 +33,7 @@ class Decoded; class VideoDecoder; class AudioDecoder; class SubtitleDecoder; +class DecoderPart; /** @class Decoder. * @brief Parent class for decoders of content. @@ -60,7 +61,7 @@ public: */ virtual void reset () {} - void maybe_seek (boost::optional& position, ContentTime time, bool accurate); + void maybe_seek (boost::optional position, ContentTime time, bool accurate); private: /** Seek so that the next pass() will yield the next thing diff --git a/src/lib/decoder_part.cc b/src/lib/decoder_part.cc index f210bd7ae..6d53e4a77 100644 --- a/src/lib/decoder_part.cc +++ b/src/lib/decoder_part.cc @@ -34,5 +34,5 @@ DecoderPart::DecoderPart (Decoder* parent, shared_ptr log) void DecoderPart::maybe_seek (ContentTime time, bool accurate) { - _parent->maybe_seek (_position, time, accurate); + _parent->maybe_seek (position(), time, accurate); } diff --git a/src/lib/decoder_part.h b/src/lib/decoder_part.h index 1a8794527..ed92d43b4 100644 --- a/src/lib/decoder_part.h +++ b/src/lib/decoder_part.h @@ -40,13 +40,7 @@ public: return _ignore; } - void set_position (ContentTime position) { - _position = position; - } - - boost::optional position () const { - return _position; - } + virtual boost::optional position () const = 0; void maybe_seek (ContentTime time, bool accurate); @@ -56,7 +50,6 @@ protected: private: bool _ignore; - boost::optional _position; }; #endif diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index c732a5173..b6b6e594d 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -426,8 +426,6 @@ FFmpegDecoder::decode_audio_packet () LOG_WARNING ("Crazy timestamp %1", to_string (ct)); } - audio->set_position (ct); - /* Give this data provided there is some, and its time is sane */ if (ct >= ContentTime() && data->frames() > 0) { audio->give (*stream, data, ct); @@ -479,7 +477,6 @@ FFmpegDecoder::decode_video_packet () shared_ptr (new RawImageProxy (image)), llrint (pts * _ffmpeg_content->active_video_frame_rate ()) ); - video->set_position (ContentTime::from_seconds (pts)); } else { LOG_WARNING_NC ("Dropping frame without PTS"); } @@ -510,7 +507,6 @@ FFmpegDecoder::decode_subtitle_packet () FFmpegSubtitlePeriod sub_period = subtitle_period (sub); ContentTimePeriod period; period.from = sub_period.from + _pts_offset; - subtitle->set_position (period.from); /* We can't trust the `to' time from sub_period as there are some decoders which give a sub_period time for `to' which is subsequently overridden by a `stop' subtitle; see also FFmpegExaminer. diff --git a/src/lib/image_decoder.cc b/src/lib/image_decoder.cc index 28fc9c0a5..dae73663c 100644 --- a/src/lib/image_decoder.cc +++ b/src/lib/image_decoder.cc @@ -72,7 +72,6 @@ ImageDecoder::pass (PassReason, bool) } } - video->set_position (ContentTime::from_frames (_frame_video_position, _image_content->active_video_frame_rate ())); video->give (_image, _frame_video_position); ++_frame_video_position; return false; diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc index 9ec030b38..c59406c36 100644 --- a/src/lib/subtitle_decoder.cc +++ b/src/lib/subtitle_decoder.cc @@ -63,6 +63,7 @@ void SubtitleDecoder::give_image (ContentTimePeriod period, shared_ptr image, dcpomatic::Rect rect) { _decoded_image.push_back (ContentImageSubtitle (period, image, rect)); + _position = period.from; } void @@ -79,6 +80,7 @@ SubtitleDecoder::give_text (ContentTimePeriod period, list } _decoded_text.push_back (ContentTextSubtitle (period, s)); + _position = period.from; } /** Get the subtitles that correspond to a given list of periods. @@ -168,6 +170,7 @@ SubtitleDecoder::seek (ContentTime t, bool) { _log->log (String::compose ("SD seek to %1", to_string(t)), LogEntry::TYPE_DEBUG_DECODE); reset (); + _position.reset (); } void diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h index dfa3d6d90..e5e931669 100644 --- a/src/lib/subtitle_decoder.h +++ b/src/lib/subtitle_decoder.h @@ -63,6 +63,14 @@ public: return _content; } + boost::optional position () const { + return _position; + } + + void reset_position () { + _position.reset (); + } + private: std::list _decoded_image; @@ -74,6 +82,8 @@ private: boost::function (ContentTimePeriod, bool)> _image_during; boost::function (ContentTimePeriod, bool)> _text_during; + + boost::optional _position; }; #endif diff --git a/src/lib/text_subtitle_decoder.cc b/src/lib/text_subtitle_decoder.cc index ec60bd36b..dd64cb5d9 100644 --- a/src/lib/text_subtitle_decoder.cc +++ b/src/lib/text_subtitle_decoder.cc @@ -69,7 +69,6 @@ TextSubtitleDecoder::pass (PassReason, bool) ContentTimePeriod const p = content_time_period (_subtitles[_next]); subtitle->give_text (p, _subtitles[_next]); - subtitle->set_position (p.from); ++_next; return false; diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 1cde53e81..0e9ee0c1a 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -274,6 +274,7 @@ VideoDecoder::give (shared_ptr image, Frame frame) } _log->log (String::compose ("VD receives %1", frame), LogEntry::TYPE_DEBUG_DECODE); + _position = ContentTime::from_frames (frame, _content->active_video_frame_rate()); /* Work out what we are going to push into _decoded next */ list to_push; @@ -389,4 +390,5 @@ VideoDecoder::seek (ContentTime s, bool accurate) _decoded.clear (); _last_seek_time = s; _last_seek_accurate = accurate; + _position.reset (); } diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 4f764d203..156ee4222 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -60,6 +60,14 @@ public: void seek (ContentTime time, bool accurate); void give (boost::shared_ptr, Frame frame); + boost::optional position () const { + return _position; + } + + void reset_position () { + _position.reset (); + } + private: std::list decoded (Frame frame); @@ -75,6 +83,7 @@ private: * it has no more to give. */ boost::optional _no_data_frame; + boost::optional _position; }; #endif diff --git a/src/lib/video_mxf_decoder.cc b/src/lib/video_mxf_decoder.cc index 90a58a16e..dc4f8d60b 100644 --- a/src/lib/video_mxf_decoder.cc +++ b/src/lib/video_mxf_decoder.cc @@ -89,7 +89,6 @@ VideoMXFDecoder::pass (PassReason, bool) ); } - video->set_position (_next); _next += ContentTime::from_frames (1, vfr); return false; }