diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-04-07 01:25:12 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-04-07 01:25:12 +0100 |
| commit | 21ae33095a251da25b3c5a85bc52fad63e04db0b (patch) | |
| tree | a67e784269fd9f1f62967cd0f660cf134848bf64 /src/lib | |
| parent | 3cc96e5cc65456f4aeb4625f56087da33da47b48 (diff) | |
Fix still video playback.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 12 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/imagemagick_decoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/imagemagick_decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/player.cc | 9 | ||||
| -rw-r--r-- | src/lib/video_content.cc | 2 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 10 | ||||
| -rw-r--r-- | src/lib/video_decoder.h | 8 |
8 files changed, 28 insertions, 21 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index fdc5189a6..a0949f635 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -400,7 +400,7 @@ FFmpegDecoder::deinterleave_audio (uint8_t** data, int size) } float -FFmpegDecoder::frames_per_second () const +FFmpegDecoder::video_frame_rate () const { AVStream* s = _format_context->streams[_video_stream]; @@ -550,7 +550,7 @@ void FFmpegDecoder::out_with_sync () { /* Where we are in the output, in seconds */ - double const out_pts_seconds = video_frame() / frames_per_second(); + double const out_pts_seconds = video_frame() / video_frame_rate(); /* Where we are in the source, in seconds */ double const source_pts_seconds = av_q2d (_format_context->streams[_packet.stream_index]->time_base) @@ -567,17 +567,17 @@ FFmpegDecoder::out_with_sync () /* Difference between where we are and where we should be */ double const delta = source_pts_seconds - _first_video.get() - out_pts_seconds; - double const one_frame = 1 / frames_per_second(); + double const one_frame = 1 / video_frame_rate(); /* Insert frames if required to get out_pts_seconds up to pts_seconds */ if (delta > one_frame) { int const extra = rint (delta / one_frame); for (int i = 0; i < extra; ++i) { - repeat_last_video (); + repeat_last_video (frame_time ()); _film->log()->log ( String::compose ( N_("Extra video frame inserted at %1s; source frame %2, source PTS %3 (at %4 fps)"), - out_pts_seconds, video_frame(), source_pts_seconds, frames_per_second() + out_pts_seconds, video_frame(), source_pts_seconds, video_frame_rate() ) ); } @@ -613,7 +613,7 @@ FFmpegDecoder::film_changed (Film::Property p) ContentVideoFrame FFmpegDecoder::video_length () const { - return (double(_format_context->duration) / AV_TIME_BASE) * frames_per_second(); + return (double(_format_context->duration) / AV_TIME_BASE) * video_frame_rate(); } double diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 5023ac56c..cd37d20c6 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -60,7 +60,7 @@ public: FFmpegDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const FFmpegContent>, bool video, bool audio, bool subtitles, bool video_sync); ~FFmpegDecoder (); - float frames_per_second () const; + float video_frame_rate () const; libdcp::Size native_size () const; ContentVideoFrame video_length () const; int time_base_numerator () const; diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index dff177548..6a2be1a7c 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -66,7 +66,7 @@ ImageMagickDecoder::pass () } if (have_last_video ()) { - repeat_last_video (); + repeat_last_video (double (_position) / 24); _position++; return false; } @@ -92,7 +92,7 @@ ImageMagickDecoder::pass () image = image->crop (_film->crop(), true); - emit_video (image, 0); + emit_video (image, double (_position) / 24); ++_position; return false; diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index 424cefe08..cb524b44b 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -30,7 +30,7 @@ class ImageMagickDecoder : public VideoDecoder public: ImageMagickDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const ImageMagickContent>); - float frames_per_second () const { + float video_frame_rate () const { return 24; } diff --git a/src/lib/player.cc b/src/lib/player.cc index d1f047851..ac046fcc0 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -277,7 +277,14 @@ Player::last_video_time () const case Playlist::VIDEO_FFMPEG: return _ffmpeg_decoder->last_source_time (); case Playlist::VIDEO_IMAGEMAGICK: - return (*_imagemagick_decoder)->last_source_time (); + { + double t = 0; + for (list<shared_ptr<ImageMagickDecoder> >::const_iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoder; ++i) { + t += (*i)->video_length() / (*i)->video_frame_rate (); + } + + return t + (*_imagemagick_decoder)->last_source_time (); + } } return 0; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 8176c5c41..9fb2b9bce 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -73,7 +73,7 @@ VideoContent::take_from_video_decoder (shared_ptr<VideoDecoder> d) { /* These decoder calls could call other content methods which take a lock on the mutex */ libdcp::Size const vs = d->native_size (); - float const vfr = d->frames_per_second (); + float const vfr = d->video_frame_rate (); { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 47385cc61..fd2b28d7f 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -50,8 +50,7 @@ VideoDecoder::emit_video (shared_ptr<Image> image, double t) sub = _timed_subtitle->subtitle (); } - signal_video (image, false, sub); - _last_source_time = t; + signal_video (image, false, sub, t); } bool @@ -65,14 +64,14 @@ VideoDecoder::have_last_video () const * we will generate a black frame. */ void -VideoDecoder::repeat_last_video () +VideoDecoder::repeat_last_video (double t) { if (!_last_image) { _last_image.reset (new SimpleImage (pixel_format(), native_size(), true)); _last_image->make_black (); } - signal_video (_last_image, true, _last_subtitle); + signal_video (_last_image, true, _last_subtitle, t); } /** Emit our signal to say that some video data is ready. @@ -81,7 +80,7 @@ VideoDecoder::repeat_last_video () * @param sub Subtitle for this frame, or 0. */ void -VideoDecoder::signal_video (shared_ptr<Image> image, bool same, shared_ptr<Subtitle> sub) +VideoDecoder::signal_video (shared_ptr<Image> image, bool same, shared_ptr<Subtitle> sub, double t) { TIMING (N_("Decoder emits %1"), _video_frame); Video (image, same, sub); @@ -89,6 +88,7 @@ VideoDecoder::signal_video (shared_ptr<Image> image, bool same, shared_ptr<Subti _last_image = image; _last_subtitle = sub; + _last_source_time = t; } /** Set up the current subtitle. This will be put onto frames that diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 74343e856..c04874342 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -30,8 +30,8 @@ class VideoDecoder : public VideoSource, public virtual Decoder public: VideoDecoder (boost::shared_ptr<const Film>); - /** @return video frames per second, or 0 if unknown */ - virtual float frames_per_second () const = 0; + /** @return video frame rate second, or 0 if unknown */ + virtual float video_frame_rate () const = 0; /** @return native size in pixels */ virtual libdcp::Size native_size () const = 0; /** @return length according to our content's header */ @@ -59,10 +59,10 @@ protected: void emit_video (boost::shared_ptr<Image>, double); void emit_subtitle (boost::shared_ptr<TimedSubtitle>); bool have_last_video () const; - void repeat_last_video (); + void repeat_last_video (double); private: - void signal_video (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>); + void signal_video (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double); int _video_frame; double _last_source_time; |
