summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-12-18 21:13:53 +0000
committerCarl Hetherington <cth@carlh.net>2012-12-18 21:13:53 +0000
commit602fd58eff38fdfccc489b9f77b3ff0ca0009566 (patch)
treef44645730c3b412fcc0c79f4bca73260567a362d /src/lib
parent039a55081427b1ff0026cd6b9ca787526d37ef92 (diff)
parent0330d9b2924767d9240c5a25e9ed4327eb0a73bd (diff)
Fix merge.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/decoder.cc15
-rw-r--r--src/lib/decoder.h6
-rw-r--r--src/lib/ffmpeg_decoder.cc27
-rw-r--r--src/lib/ffmpeg_decoder.h4
-rw-r--r--src/lib/imagemagick_decoder.cc16
-rw-r--r--src/lib/imagemagick_decoder.h3
-rw-r--r--src/lib/subtitle.cc11
-rw-r--r--src/lib/subtitle.h2
-rw-r--r--src/lib/video_decoder.cc11
-rw-r--r--src/lib/video_decoder.h12
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;