diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-12-18 21:13:53 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-12-18 21:13:53 +0000 |
| commit | 602fd58eff38fdfccc489b9f77b3ff0ca0009566 (patch) | |
| tree | f44645730c3b412fcc0c79f4bca73260567a362d /src/lib | |
| parent | 039a55081427b1ff0026cd6b9ca787526d37ef92 (diff) | |
| parent | 0330d9b2924767d9240c5a25e9ed4327eb0a73bd (diff) | |
Fix merge.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/decoder.cc | 15 | ||||
| -rw-r--r-- | src/lib/decoder.h | 6 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 27 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/imagemagick_decoder.cc | 16 | ||||
| -rw-r--r-- | src/lib/imagemagick_decoder.h | 3 | ||||
| -rw-r--r-- | src/lib/subtitle.cc | 11 | ||||
| -rw-r--r-- | src/lib/subtitle.h | 2 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 11 | ||||
| -rw-r--r-- | src/lib/video_decoder.h | 12 |
10 files changed, 74 insertions, 33 deletions
diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index 7d4085045..61e63460b 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -57,8 +57,21 @@ Decoder::Decoder (boost::shared_ptr<Film> f, boost::shared_ptr<const DecodeOptio _film_connection = f->Changed.connect (bind (&Decoder::film_changed, this, _1)); } +/** Seek. + * @param p Position as a source timestamp in seconds. + * @return true on error. + */ +bool +Decoder::seek (double p) +{ + throw DecodeError ("decoder does not support seek"); +} + +/** Seek so that the next frame we will produce is the same as the last one. + * @return true on error. + */ bool -Decoder::seek (SourceFrame f) +Decoder::seek_to_last () { throw DecodeError ("decoder does not support seek"); } diff --git a/src/lib/decoder.h b/src/lib/decoder.h index b8278ff80..3908afa2f 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -58,10 +58,8 @@ public: virtual ~Decoder () {} virtual bool pass () = 0; - /** Seek. - * @return true on error. - */ - virtual bool seek (SourceFrame); + virtual bool seek (double); + virtual bool seek_to_last (); boost::signals2::signal<void()> OutputChanged; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 0e4446a86..c4ca00fa6 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -334,7 +334,7 @@ FFmpegDecoder::pass () if (sub.num_rects > 0) { shared_ptr<TimedSubtitle> ts; try { - emit_subtitle (shared_ptr<TimedSubtitle> (new TimedSubtitle (sub, _first_video.get()))); + emit_subtitle (shared_ptr<TimedSubtitle> (new TimedSubtitle (sub))); } catch (...) { /* some problem with the subtitle; we probably didn't understand it */ } @@ -543,24 +543,35 @@ FFmpegDecoder::filter_and_emit_video (AVFrame* frame) list<shared_ptr<Image> > images = graph->process (frame); - SourceFrame const sf = av_q2d (_format_context->streams[_video_stream]->time_base) - * av_frame_get_best_effort_timestamp(_frame) * frames_per_second(); + double const st = av_frame_get_best_effort_timestamp(_frame) * av_q2d (_format_context->streams[_video_stream]->time_base); for (list<shared_ptr<Image> >::iterator i = images.begin(); i != images.end(); ++i) { - emit_video (*i, sf); + emit_video (*i, st); } } bool -FFmpegDecoder::seek (SourceFrame f) +FFmpegDecoder::seek (double p) { - int64_t const vt = static_cast<int64_t>(f) / (av_q2d (_format_context->streams[_video_stream]->time_base) * frames_per_second()); + return do_seek (p, false); +} - /* This AVSEEK_FLAG_BACKWARD is a bit of a hack; without it, if we ask for a seek to the same place as last time +bool +FFmpegDecoder::seek_to_last () +{ + /* This AVSEEK_FLAG_BACKWARD in do_seek is a bit of a hack; without it, if we ask for a seek to the same place as last time (used when we change decoder parameters and want to re-fetch the frame) we end up going forwards rather than staying in the same place. */ - int const r = av_seek_frame (_format_context, _video_stream, vt, (f == last_source_frame() ? AVSEEK_FLAG_BACKWARD : 0)); + return do_seek (last_source_time(), true); +} + +bool +FFmpegDecoder::do_seek (double p, bool backwards) +{ + int64_t const vt = p / av_q2d (_format_context->streams[_video_stream]->time_base); + + int const r = av_seek_frame (_format_context, _video_stream, vt, backwards ? AVSEEK_FLAG_BACKWARD : 0); avcodec_flush_buffers (_video_codec_context); if (_subtitle_codec_context) { diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 2011ef72f..89534a38c 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -100,11 +100,13 @@ public: void set_audio_stream (boost::shared_ptr<AudioStream>); void set_subtitle_stream (boost::shared_ptr<SubtitleStream>); - bool seek (SourceFrame); + bool seek (double); + bool seek_to_last (); private: bool pass (); + bool do_seek (double p, bool); PixelFormat pixel_format () const; AVSampleFormat audio_sample_format () const; int bytes_per_audio_sample () const; diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 5713e68f9..131eaa500 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -108,8 +108,22 @@ ImageMagickDecoder::pixel_format () const } bool -ImageMagickDecoder::seek (SourceFrame f) +ImageMagickDecoder::seek_to_last () { + if (_iter == _files.end()) { + _iter = _files.begin(); + } else { + --_iter; + } + + return false; +} + +bool +ImageMagickDecoder::seek (double t) +{ + int const f = t * frames_per_second(); + _iter = _files.begin (); for (int i = 0; i < f; ++i) { if (_iter == _files.end()) { diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index cf417d373..6f426f308 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -56,7 +56,8 @@ public: return false; } - bool seek (SourceFrame); + bool seek (double); + bool seek_to_last (); protected: bool pass (); diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc index 39f8faa68..c52d3ac66 100644 --- a/src/lib/subtitle.cc +++ b/src/lib/subtitle.cc @@ -31,14 +31,15 @@ using namespace boost; /** Construct a TimedSubtitle. This is a subtitle image, position, * and a range of time over which it should be shown. * @param sub AVSubtitle to read. - * @param c Fractional seconds that should be subtracted from the AVSubtitle's PTS. */ -TimedSubtitle::TimedSubtitle (AVSubtitle const & sub, double c) +TimedSubtitle::TimedSubtitle (AVSubtitle const & sub) { assert (sub.rects > 0); - /* subtitle PTS in seconds */ - double const packet_time = ((sub.pts / AV_TIME_BASE) + float (sub.pts % AV_TIME_BASE) / 1e6) - c; + /* Subtitle PTS in seconds (within the source, not taking into account any of the + source that we may have chopped off for the DCP) + */ + double const packet_time = static_cast<double> (sub.pts) / AV_TIME_BASE; /* hence start time for this sub */ _from = packet_time + (double (sub.start_display_time) / 1e3); @@ -76,7 +77,7 @@ TimedSubtitle::TimedSubtitle (AVSubtitle const & sub, double c) _subtitle.reset (new Subtitle (Position (rect->x, rect->y), image)); } -/** @param t Time in seconds from the start of the film */ +/** @param t Time in seconds from the start of the source */ bool TimedSubtitle::displayed_at (double t) const { diff --git a/src/lib/subtitle.h b/src/lib/subtitle.h index 590e0dd31..38ba4e70e 100644 --- a/src/lib/subtitle.h +++ b/src/lib/subtitle.h @@ -63,7 +63,7 @@ subtitle_transformed_area ( class TimedSubtitle { public: - TimedSubtitle (AVSubtitle const &, double c); + TimedSubtitle (AVSubtitle const &); bool displayed_at (double t) const; diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 4c05d5fcd..e723610b3 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -31,25 +31,26 @@ using boost::optional; VideoDecoder::VideoDecoder (shared_ptr<Film> f, shared_ptr<const DecodeOptions> o, Job* j) : Decoder (f, o, j) , _video_frame (0) - , _last_source_frame (0) + , _last_source_time (0) { } /** Called by subclasses to tell the world that some video data is ready. * We find a subtitle then emit it for listeners. - * @param frame to emit. + * @param image frame to emit. + * @param t Time of the frame within the source, in seconds. */ void -VideoDecoder::emit_video (shared_ptr<Image> image, SourceFrame f) +VideoDecoder::emit_video (shared_ptr<Image> image, double t) { shared_ptr<Subtitle> sub; - if (_timed_subtitle && _timed_subtitle->displayed_at (f / _film->frames_per_second())) { + if (_timed_subtitle && _timed_subtitle->displayed_at (t)) { sub = _timed_subtitle->subtitle (); } signal_video (image, sub); - _last_source_frame = f; + _last_source_time = t; } void diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index f682941d1..97bbb0e48 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -45,7 +45,7 @@ public: void set_progress () const; - SourceFrame video_frame () const { + int video_frame () const { return _video_frame; } @@ -57,15 +57,15 @@ public: return _subtitle_streams; } - SourceFrame last_source_frame () const { - return _last_source_frame; + double last_source_time () const { + return _last_source_time; } protected: virtual PixelFormat pixel_format () const = 0; - void emit_video (boost::shared_ptr<Image>, SourceFrame); + void emit_video (boost::shared_ptr<Image>, double); void emit_subtitle (boost::shared_ptr<TimedSubtitle>); void repeat_last_video (); @@ -77,8 +77,8 @@ protected: private: void signal_video (boost::shared_ptr<Image>, boost::shared_ptr<Subtitle>); - SourceFrame _video_frame; - SourceFrame _last_source_frame; + int _video_frame; + double _last_source_time; boost::shared_ptr<TimedSubtitle> _timed_subtitle; |
