diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-03-05 23:10:16 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-03-05 23:10:16 +0000 |
| commit | 18614dda0d53b713ace5ad1df57298d049dba87f (patch) | |
| tree | e68887db77ec57a2de344f8230b0e801030bdca5 /src/lib | |
| parent | 8fa7b8c13a76bd54207156de7bb0d09316bad379 (diff) | |
Split timed from untimed sinks / sources. Should produce same output, in theory.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/ab_transcoder.cc | 7 | ||||
| -rw-r--r-- | src/lib/audio_decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/audio_sink.h | 7 | ||||
| -rw-r--r-- | src/lib/audio_source.cc | 6 | ||||
| -rw-r--r-- | src/lib/audio_source.h | 12 | ||||
| -rw-r--r-- | src/lib/combiner.cc | 8 | ||||
| -rw-r--r-- | src/lib/combiner.h | 6 | ||||
| -rw-r--r-- | src/lib/delay_line.cc | 7 | ||||
| -rw-r--r-- | src/lib/delay_line.h | 4 | ||||
| -rw-r--r-- | src/lib/external_audio_decoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 8 | ||||
| -rw-r--r-- | src/lib/gain.cc | 2 | ||||
| -rw-r--r-- | src/lib/gain.h | 2 | ||||
| -rw-r--r-- | src/lib/imagemagick_decoder.cc | 3 | ||||
| -rw-r--r-- | src/lib/matcher.cc | 6 | ||||
| -rw-r--r-- | src/lib/matcher.h | 6 | ||||
| -rw-r--r-- | src/lib/processor.h | 42 | ||||
| -rw-r--r-- | src/lib/transcoder.cc | 3 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 10 | ||||
| -rw-r--r-- | src/lib/video_decoder.h | 6 | ||||
| -rw-r--r-- | src/lib/video_sink.h | 12 | ||||
| -rw-r--r-- | src/lib/video_source.cc | 6 | ||||
| -rw-r--r-- | src/lib/video_source.h | 23 |
23 files changed, 110 insertions, 82 deletions
diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 4ed5d02ca..373549b57 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -70,14 +70,15 @@ ABTranscoder::ABTranscoder ( _db.video->set_subtitle_stream (_film_a->subtitle_stream ()); _da.audio->set_audio_stream (_film_a->audio_stream ()); - _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3)); - _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3)); + _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4)); + _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4)); if (_matcher) { _combiner->connect_video (_matcher); _matcher->connect_video (_encoder); } else { - _combiner->connect_video (_encoder); + /* Remove timestamp from the output of the combiner */ + _combiner->Video.connect (bind (&Encoder::process_video, _encoder, _1, _2, _3)); } if (_matcher && _delay_line) { diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 9bef8e0e7..cfe94b528 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -31,7 +31,7 @@ /** @class AudioDecoder. * @brief Parent class for audio decoders. */ -class AudioDecoder : public AudioSource, public virtual Decoder +class AudioDecoder : public TimedAudioSource, public virtual Decoder { public: AudioDecoder (boost::shared_ptr<Film>, DecodeOptions); diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h index 11d578a60..a222bd6a0 100644 --- a/src/lib/audio_sink.h +++ b/src/lib/audio_sink.h @@ -27,4 +27,11 @@ public: virtual void process_audio (boost::shared_ptr<AudioBuffers>) = 0; }; +class TimedAudioSink +{ +public: + /** Call with some audio data */ + virtual void process_audio (boost::shared_ptr<AudioBuffers>, double t) = 0; +}; + #endif diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc index 53b0dda15..bca3562cf 100644 --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@ -28,3 +28,9 @@ AudioSource::connect_audio (shared_ptr<AudioSink> s) { Audio.connect (bind (&AudioSink::process_audio, s, _1)); } + +void +TimedAudioSource::connect_audio (shared_ptr<TimedAudioSink> s) +{ + Audio.connect (bind (&TimedAudioSink::process_audio, s, _1, _2)); +} diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h index 5a1510d3c..3dc998cca 100644 --- a/src/lib/audio_source.h +++ b/src/lib/audio_source.h @@ -28,6 +28,7 @@ class AudioBuffers; class AudioSink; +class TimedAudioSink; /** A class that emits audio data */ class AudioSource @@ -39,4 +40,15 @@ public: void connect_audio (boost::shared_ptr<AudioSink>); }; + +/** A class that emits audio data with timestamps */ +class TimedAudioSource +{ +public: + /** Emitted when some audio data is ready */ + boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, double)> Audio; + + void connect_audio (boost::shared_ptr<TimedAudioSink>); +}; + #endif diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 68aafd2a2..e628f3a84 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; Combiner::Combiner (Log* log) - : VideoProcessor (log) + : Processor (log) { } @@ -33,7 +33,7 @@ Combiner::Combiner (Log* log) * @param image Frame image. */ void -Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>) +Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>, double) { _image = image; } @@ -43,7 +43,7 @@ Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>) * @param sub Subtitle (which will be put onto the whole frame) */ void -Combiner::process_video_b (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub) +Combiner::process_video_b (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub, double t) { /* Copy the right half of this image into our _image */ /* XXX: this should probably be in the Image class */ @@ -62,6 +62,6 @@ Combiner::process_video_b (shared_ptr<Image> image, bool, shared_ptr<Subtitle> s } } - Video (_image, false, sub); + Video (_image, false, sub, t); _image.reset (); } diff --git a/src/lib/combiner.h b/src/lib/combiner.h index 7fad1aeae..c52c53ed9 100644 --- a/src/lib/combiner.h +++ b/src/lib/combiner.h @@ -28,13 +28,13 @@ * one image used for the left half of the screen and the other for * the right. */ -class Combiner : public VideoProcessor +class Combiner : public Processor, public TimedVideoSink, public TimedVideoSource { public: Combiner (Log* log); - void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s); - void process_video_b (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s); + void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double t); + void process_video_b (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double t); private: /** The image that we are currently working on */ diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index 4ad172781..84785cfc6 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -31,7 +31,7 @@ using boost::shared_ptr; * @param frames Delay in frames, +ve to move audio later. */ DelayLine::DelayLine (Log* log, int channels, int frames) - : AudioProcessor (log) + : Processor (log) , _negative_delay_remaining (0) , _frames (frames) { @@ -47,8 +47,9 @@ DelayLine::DelayLine (Log* log, int channels, int frames) } } +/* XXX: can we just get rid of all this and fiddle with the timestamp? */ void -DelayLine::process_audio (shared_ptr<AudioBuffers> data) +DelayLine::process_audio (shared_ptr<AudioBuffers> data, double t) { if (_buffers) { /* We have some buffers, so we are moving the audio later */ @@ -89,5 +90,5 @@ DelayLine::process_audio (shared_ptr<AudioBuffers> data) } } - Audio (data); + Audio (data, t); } diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index 4d6f1313b..8c4a3953c 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -23,12 +23,12 @@ class AudioBuffers; /** A delay line for audio */ -class DelayLine : public AudioProcessor +class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource { public: DelayLine (Log* log, int channels, int frames); - void process_audio (boost::shared_ptr<AudioBuffers>); + void process_audio (boost::shared_ptr<AudioBuffers>, double); private: boost::shared_ptr<AudioBuffers> _buffers; diff --git a/src/lib/external_audio_decoder.cc b/src/lib/external_audio_decoder.cc index 1248b5a3b..50e5852c5 100644 --- a/src/lib/external_audio_decoder.cc +++ b/src/lib/external_audio_decoder.cc @@ -115,6 +115,7 @@ ExternalAudioDecoder::pass () sf_count_t const block = _audio_stream->sample_rate() / 2; shared_ptr<AudioBuffers> audio (new AudioBuffers (_audio_stream->channels(), block)); + sf_count_t done = 0; while (frames > 0) { sf_count_t const this_time = min (block, frames); for (size_t i = 0; i < sndfiles.size(); ++i) { @@ -126,7 +127,8 @@ ExternalAudioDecoder::pass () } audio->set_frames (this_time); - Audio (audio); + Audio (audio, double(done) / _audio_stream->sample_rate()); + done += this_time; frames -= this_time; } diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index ac25844e3..32c8e224a 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -640,7 +640,8 @@ FFmpegDecoder::out_with_sync () if (delta > one_frame) { int const extra = rint (delta / one_frame); for (int i = 0; i < extra; ++i) { - repeat_last_video (); + /* XXX: timestamp is wrong */ + repeat_last_video (source_pts_seconds); _film->log()->log ( String::compose ( N_("Extra video frame inserted at %1s; source frame %2, source PTS %3 (at %4 fps)"), @@ -739,7 +740,8 @@ FFmpegDecoder::decode_audio_packet () if (s) { shared_ptr<AudioBuffers> audio (new AudioBuffers (ffa->channels(), s)); audio->make_silent (); - Audio (audio); + /* XXX: this time stamp is wrong */ + Audio (audio, source_pts_seconds); } } @@ -748,7 +750,7 @@ FFmpegDecoder::decode_audio_packet () ); assert (_audio_codec_context->channels == _film->audio_channels()); - Audio (deinterleave_audio (_frame->data, data_size)); + Audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds ); } } diff --git a/src/lib/gain.cc b/src/lib/gain.cc index cec3b3c62..35ce27cea 100644 --- a/src/lib/gain.cc +++ b/src/lib/gain.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; /** @param gain gain in dB */ Gain::Gain (Log* log, float gain) - : AudioProcessor (log) + : Processor (log) , _gain (gain) { diff --git a/src/lib/gain.h b/src/lib/gain.h index 716ee9b51..449473582 100644 --- a/src/lib/gain.h +++ b/src/lib/gain.h @@ -19,7 +19,7 @@ #include "processor.h" -class Gain : public AudioProcessor +class Gain : public Processor, public AudioSink, public AudioSource { public: Gain (Log* log, float gain); diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 5dc0b7b06..38dace6de 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -77,7 +77,8 @@ ImageMagickDecoder::pass () return true; } - repeat_last_video (); + /* XXX: timestamp is wrong */ + repeat_last_video (0); return false; } diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 4cd264338..3a513b24e 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -27,7 +27,7 @@ using std::min; using boost::shared_ptr; Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) - : AudioVideoProcessor (log) + : Processor (log) , _sample_rate (sample_rate) , _frames_per_second (frames_per_second) , _video_frames (0) @@ -37,7 +37,7 @@ Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) } void -Matcher::process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s) +Matcher::process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s, double) { Video (i, same, s); _video_frames++; @@ -47,7 +47,7 @@ Matcher::process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr } void -Matcher::process_audio (boost::shared_ptr<AudioBuffers> b) +Matcher::process_audio (boost::shared_ptr<AudioBuffers> b, double) { Audio (b); _audio_frames += b->frames (); diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 60bb87432..4a66f4e70 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -21,12 +21,12 @@ #include "processor.h" #include "ffmpeg_compatibility.h" -class Matcher : public AudioVideoProcessor +class Matcher : public Processor, public TimedVideoSink, public TimedAudioSink, public VideoSource, public AudioSource { public: Matcher (Log* log, int sample_rate, float frames_per_second); - void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s); - void process_audio (boost::shared_ptr<AudioBuffers>); + void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double t); + void process_audio (boost::shared_ptr<AudioBuffers>, double t); void process_end (); private: diff --git a/src/lib/processor.h b/src/lib/processor.h index 19d7c4b0c..863bfdbb5 100644 --- a/src/lib/processor.h +++ b/src/lib/processor.h @@ -53,46 +53,4 @@ protected: Log* _log; ///< log to write to }; -/** @class AudioVideoProcessor - * @brief A processor which handles both video and audio data. - */ -class AudioVideoProcessor : public Processor, public VideoSource, public VideoSink, public AudioSource, public AudioSink -{ -public: - /** Construct an AudioVideoProcessor. - * @param log Log to write to. - */ - AudioVideoProcessor (Log* log) - : Processor (log) - {} -}; - -/** @class AudioProcessor - * @brief A processor which handles just audio data. - */ -class AudioProcessor : public Processor, public AudioSource, public AudioSink -{ -public: - /** Construct an AudioProcessor. - * @param log Log to write to. - */ - AudioProcessor (Log* log) - : Processor (log) - {} -}; - -/** @class VideoProcessor - * @brief A processor which handles just video data. - */ -class VideoProcessor : public Processor, public VideoSource, public VideoSink -{ -public: - /** Construct an VideoProcessor. - * @param log Log to write to. - */ - VideoProcessor (Log* log) - : Processor (log) - {} -}; - #endif diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 9720ca56a..3beda2b8b 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -72,7 +72,8 @@ Transcoder::Transcoder (shared_ptr<Film> f, DecodeOptions o, Job* j, shared_ptr< _decoders.video->connect_video (_matcher); _matcher->connect_video (_encoder); } else { - _decoders.video->connect_video (_encoder); + /* Discard timestamps here */ + _decoders.video->Video.connect (boost::bind (&Encoder::process_video, _encoder, _1, _2, _3)); } if (_matcher && _delay_line && _decoders.audio) { diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 891720f6b..773688b34 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -51,7 +51,7 @@ VideoDecoder::emit_video (shared_ptr<Image> image, double t) sub = _timed_subtitle->subtitle (); } - signal_video (image, false, sub); + signal_video (image, false, sub, t); _last_source_time = t; } @@ -60,14 +60,14 @@ VideoDecoder::emit_video (shared_ptr<Image> image, double t) * 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. @@ -76,10 +76,10 @@ 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); + Video (image, same, sub, t); ++_video_frame; _last_image = image; diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 283ab5d88..5e9c60d08 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -24,7 +24,7 @@ #include "stream.h" #include "decoder.h" -class VideoDecoder : public VideoSource, public virtual Decoder +class VideoDecoder : public TimedVideoSource, public virtual Decoder { public: VideoDecoder (boost::shared_ptr<Film>, DecodeOptions); @@ -67,7 +67,7 @@ protected: void emit_video (boost::shared_ptr<Image>, double); void emit_subtitle (boost::shared_ptr<TimedSubtitle>); - void repeat_last_video (); + void repeat_last_video (double t); /** Subtitle stream to use when decoding */ boost::shared_ptr<SubtitleStream> _subtitle_stream; @@ -75,7 +75,7 @@ protected: std::vector<boost::shared_ptr<SubtitleStream> > _subtitle_streams; 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; diff --git a/src/lib/video_sink.h b/src/lib/video_sink.h index 7c128cf73..32c7f3b38 100644 --- a/src/lib/video_sink.h +++ b/src/lib/video_sink.h @@ -37,4 +37,16 @@ public: virtual void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s) = 0; }; +class TimedVideoSink +{ +public: + /** Call with a frame of video. + * @param i Video frame image. + * @param same true if i is the same as last time we were called. + * @param s A subtitle that should be on this frame, or 0. + * @param t Source timestamp. + */ + virtual void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s, double t) = 0; +}; + #endif diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index 56742e2b4..af6f941fd 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -28,3 +28,9 @@ VideoSource::connect_video (shared_ptr<VideoSink> s) { Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3)); } + +void +TimedVideoSource::connect_video (shared_ptr<TimedVideoSink> s) +{ + Video.connect (bind (&TimedVideoSink::process_video, s, _1, _2, _3, _4)); +} diff --git a/src/lib/video_source.h b/src/lib/video_source.h index 893629160..705b0023a 100644 --- a/src/lib/video_source.h +++ b/src/lib/video_source.h @@ -29,11 +29,12 @@ #include "util.h" class VideoSink; +class TimedVideoSink; class Subtitle; class Image; -/** @class VideoSink - * @param A class that emits video data. +/** @class VideoSource + * @param A class that emits video data without timestamps. */ class VideoSource { @@ -49,4 +50,22 @@ public: void connect_video (boost::shared_ptr<VideoSink>); }; +/** @class TimedVideoSource + * @param A class that emits video data with timestamps. + */ +class TimedVideoSource +{ +public: + + /** Emitted when a video frame is ready. + * First parameter is the video image. + * Second parameter is true if the image is the same as the last one that was emitted. + * Third parameter is either 0 or a subtitle that should be on this frame. + * Fourth parameter is the source timestamp of this frame. + */ + boost::signals2::signal<void (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double)> Video; + + void connect_video (boost::shared_ptr<TimedVideoSink>); +}; + #endif |
