summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-04-07 01:25:12 +0100
committerCarl Hetherington <cth@carlh.net>2013-04-07 01:25:12 +0100
commit21ae33095a251da25b3c5a85bc52fad63e04db0b (patch)
treea67e784269fd9f1f62967cd0f660cf134848bf64 /src/lib
parent3cc96e5cc65456f4aeb4625f56087da33da47b48 (diff)
Fix still video playback.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ffmpeg_decoder.cc12
-rw-r--r--src/lib/ffmpeg_decoder.h2
-rw-r--r--src/lib/imagemagick_decoder.cc4
-rw-r--r--src/lib/imagemagick_decoder.h2
-rw-r--r--src/lib/player.cc9
-rw-r--r--src/lib/video_content.cc2
-rw-r--r--src/lib/video_decoder.cc10
-rw-r--r--src/lib/video_decoder.h8
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;