summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-03-06 22:55:11 +0000
committerCarl Hetherington <cth@carlh.net>2013-03-06 22:55:11 +0000
commitb0802a7644c12bc039c070367440439f7afe133a (patch)
tree2fa4a2c322304f48bab0994bb37aa803fa3b344c /src
parent085d9d4966c32aa1f3661c597b4bc2b47eaefa40 (diff)
Hopefully fix up still-image generation.
Diffstat (limited to 'src')
-rw-r--r--src/lib/ffmpeg_decoder.cc2
-rw-r--r--src/lib/imagemagick_decoder.cc15
-rw-r--r--src/lib/imagemagick_decoder.h6
-rw-r--r--src/lib/matcher.cc72
-rw-r--r--src/lib/matcher.h16
-rw-r--r--src/lib/video_decoder.cc4
-rw-r--r--src/lib/video_decoder.h2
7 files changed, 47 insertions, 70 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index e1834d7f6..2d7092789 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -520,7 +520,7 @@ FFmpegDecoder::filter_and_emit_video ()
for (list<shared_ptr<Image> >::iterator i = images.begin(); i != images.end(); ++i) {
int64_t const bet = av_frame_get_best_effort_timestamp (_frame);
if (bet != AV_NOPTS_VALUE) {
- emit_video (*i, bet * av_q2d (_format_context->streams[_video_stream]->time_base));
+ emit_video (*i, false, bet * av_q2d (_format_context->streams[_video_stream]->time_base));
} else {
_film->log()->log ("Dropping frame without PTS");
}
diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc
index 119f05792..5ce22c296 100644
--- a/src/lib/imagemagick_decoder.cc
+++ b/src/lib/imagemagick_decoder.cc
@@ -31,8 +31,6 @@ using std::cout;
using boost::shared_ptr;
using libdcp::Size;
-/* XXX: reads a directory and then ignores it */
-
ImageMagickDecoder::ImageMagickDecoder (
boost::shared_ptr<Film> f, DecodeOptions o)
: Decoder (f, o)
@@ -79,8 +77,7 @@ ImageMagickDecoder::pass ()
return true;
}
- /* XXX: timestamp */
- emit_video (_image, 0);
+ emit_video (_image, true, double (video_frame()) / frames_per_second());
return false;
}
@@ -105,8 +102,7 @@ ImageMagickDecoder::pass ()
_image = image->crop (_film->crop(), true);
- /* XXX: timestamp */
- emit_video (_image, 0);
+ emit_video (_image, false, double (video_frame()) / frames_per_second());
++_iter;
return false;
@@ -134,7 +130,6 @@ ImageMagickDecoder::seek_to_last ()
bool
ImageMagickDecoder::seek (double t)
{
- /* XXX: frames_per_second == 0 */
int const f = t * frames_per_second();
_iter = _files.begin ();
@@ -155,3 +150,9 @@ ImageMagickDecoder::film_changed (Film::Property p)
OutputChanged ();
}
}
+
+float
+ImageMagickDecoder::frames_per_second () const
+{
+ return _film->source_frame_rate ();
+}
diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h
index ef550c651..ca8e819d3 100644
--- a/src/lib/imagemagick_decoder.h
+++ b/src/lib/imagemagick_decoder.h
@@ -28,10 +28,7 @@ class ImageMagickDecoder : public VideoDecoder
public:
ImageMagickDecoder (boost::shared_ptr<Film>, DecodeOptions);
- float frames_per_second () const {
- /* We don't know */
- return 0;
- }
+ float frames_per_second () const;
libdcp::Size native_size () const;
@@ -88,5 +85,4 @@ private:
std::list<std::string>::iterator _iter;
boost::shared_ptr<Image> _image;
-
};
diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc
index 93531dbc5..fbd3e3e76 100644
--- a/src/lib/matcher.cc
+++ b/src/lib/matcher.cc
@@ -49,37 +49,35 @@ Matcher::process_video (boost::shared_ptr<Image> image, bool same, boost::shared
if (!_first_input) {
_first_input = t;
}
+
+ /* Video before audio is fine, since we can make up an arbitrary difference
+ with audio samples (contrasting with video which is quantised to frames)
+ */
+
+ /* Difference between where this video is and where it should be */
+ double const delta = t - _first_input.get() - _video_frames / _frames_per_second;
+ double const one_frame = 1 / _frames_per_second;
+
+ if (delta > one_frame) {
+ /* Insert frames to make up the difference */
+ int const extra = rint (delta / one_frame);
+ for (int i = 0; i < extra; ++i) {
+ repeat_last_video ();
+ _log->log (String::compose ("Extra video frame inserted at %1s", _video_frames / _frames_per_second));
+ }
+ }
+
+ if (delta > -one_frame) {
+ Video (image, same, sub);
+ ++_video_frames;
+ } else {
+ /* We are omitting a frame to keep things right */
+ _log->log (String::compose ("Frame removed at %1s", t));
+ }
- if (_audio_frames == 0 && _pending_audio.empty ()) {
- /* No audio yet; we must postpone this frame until we have some */
- _pending_video.push_back (VideoRecord (image, same, sub, t));
- } else if (!_pending_audio.empty() && _pending_video.empty ()) {
+ if (!_pending_audio.empty() && _video_frames == 1) {
/* First video since we got audio */
- _pending_video.push_back (VideoRecord (image, same, sub, t));
fix_start ();
- } else {
- /* Normal running */
-
- /* Difference between where this video is and where it should be */
- double const delta = t - _first_input.get() - _video_frames / _frames_per_second;
- double const one_frame = 1 / _frames_per_second;
-
- if (delta > one_frame) {
- /* Insert frames to make up the difference */
- int const extra = rint (delta / one_frame);
- for (int i = 0; i < extra; ++i) {
- repeat_last_video ();
- _log->log (String::compose ("Extra video frame inserted at %1s", _video_frames / _frames_per_second));
- }
- }
-
- if (delta > -one_frame) {
- Video (image, same, sub);
- ++_video_frames;
- } else {
- /* We are omitting a frame to keep things right */
- _log->log (String::compose ("Frame removed at %1s", t));
- }
}
_last_image = image;
@@ -95,10 +93,10 @@ Matcher::process_audio (boost::shared_ptr<AudioBuffers> b, double t)
_first_input = t;
}
- if (_video_frames == 0 && _pending_video.empty ()) {
+ if (_video_frames == 0) {
/* No video yet; we must postpone these data until we have some */
_pending_audio.push_back (AudioRecord (b, t));
- } else if (!_pending_video.empty() && _pending_audio.empty ()) {
+ } else if (_video_frames > 0 && _pending_audio.empty ()) {
/* First audio since we got video */
_pending_audio.push_back (AudioRecord (b, t));
fix_start ();
@@ -126,22 +124,20 @@ Matcher::process_end ()
void
Matcher::fix_start ()
{
- assert (!_pending_video.empty ());
assert (!_pending_audio.empty ());
+ assert (_first_input);
- _log->log (String::compose ("Fixing start; video at %1, audio at %2", _pending_video.front().time, _pending_audio.front().time));
-
- match (_pending_video.front().time - _pending_audio.front().time);
+ _log->log (String::compose ("Fixing start; start at %1, audio at %2", _first_input.get(), _pending_audio.front().time));
- for (list<VideoRecord>::iterator i = _pending_video.begin(); i != _pending_video.end(); ++i) {
- process_video (i->image, i->same, i->subtitle, i->time);
- }
+ /* This will not add any video frames, since the input parameter will always be -ve.
+ Indeed, it cannot add any, since we've already started adding "real" video.
+ */
+ match (_first_input.get() - _pending_audio.front().time);
for (list<AudioRecord>::iterator i = _pending_audio.begin(); i != _pending_audio.end(); ++i) {
process_audio (i->audio, i->time);
}
- _pending_video.clear ();
_pending_audio.clear ();
}
diff --git a/src/lib/matcher.h b/src/lib/matcher.h
index 2f580b589..84ae2f73e 100644
--- a/src/lib/matcher.h
+++ b/src/lib/matcher.h
@@ -42,22 +42,6 @@ private:
boost::optional<libdcp::Size> _size;
boost::optional<int> _channels;
- struct VideoRecord {
- VideoRecord (boost::shared_ptr<Image> i, bool s, boost::shared_ptr<Subtitle> sub, double t)
- : image (i)
- , same (s)
- , subtitle (sub)
- , time (t)
- {}
-
- boost::shared_ptr<Image> image;
- bool same;
- boost::shared_ptr<Subtitle> subtitle;
- double time;
- };
-
- std::list<VideoRecord> _pending_video;
-
struct AudioRecord {
AudioRecord (boost::shared_ptr<AudioBuffers> a, double t)
: audio (a)
diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc
index 9c0d2bbe3..16a076698 100644
--- a/src/lib/video_decoder.cc
+++ b/src/lib/video_decoder.cc
@@ -45,14 +45,14 @@ VideoDecoder::VideoDecoder (shared_ptr<Film> f, DecodeOptions o)
* @param t Time of the frame within the source, in seconds.
*/
void
-VideoDecoder::emit_video (shared_ptr<Image> image, double t)
+VideoDecoder::emit_video (shared_ptr<Image> image, bool same, double t)
{
shared_ptr<Subtitle> sub;
if (_timed_subtitle && _timed_subtitle->displayed_at (t)) {
sub = _timed_subtitle->subtitle ();
}
- Video (image, false, sub, t);
+ Video (image, same, sub, t);
++_video_frame;
_last_source_time = t;
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index 1a02272a5..6e4fd48c0 100644
--- a/src/lib/video_decoder.h
+++ b/src/lib/video_decoder.h
@@ -65,7 +65,7 @@ protected:
virtual PixelFormat pixel_format () const = 0;
- void emit_video (boost::shared_ptr<Image>, double);
+ void emit_video (boost::shared_ptr<Image>, bool, double);
void emit_subtitle (boost::shared_ptr<TimedSubtitle>);
/** Subtitle stream to use when decoding */