From e3ce330c4dc3f59f4e2b942bb6111c308a3d83eb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 22:56:51 +0000 Subject: Remove believed never-failing checks for audio streams. --- src/lib/transcoder.cc | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) (limited to 'src/lib/transcoder.cc') diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 3beda2b8b..ae88116a0 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -55,33 +55,22 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< { assert (_encoder); - if (f->audio_stream()) { - shared_ptr st = f->audio_stream(); - _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); - _delay_line.reset (new DelayLine (f->log(), st->channels(), f->audio_delay() * st->sample_rate() / 1000)); - _gain.reset (new Gain (f->log(), f->audio_gain())); - } + shared_ptr st = f->audio_stream(); + _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); + _delay_line.reset (new DelayLine (f->log(), st->channels(), f->audio_delay() * st->sample_rate() / 1000)); + _gain.reset (new Gain (f->log(), f->audio_gain())); /* Set up the decoder to use the film's set streams */ _decoders.video->set_subtitle_stream (f->subtitle_stream ()); - if (_decoders.audio) { - _decoders.audio->set_audio_stream (f->audio_stream ()); - } + _decoders.audio->set_audio_stream (f->audio_stream ()); - if (_matcher) { - _decoders.video->connect_video (_matcher); - _matcher->connect_video (_encoder); - } else { - /* Discard timestamps here */ - _decoders.video->Video.connect (boost::bind (&Encoder::process_video, _encoder, _1, _2, _3)); - } + _decoders.video->connect_video (_matcher); + _matcher->connect_video (_encoder); - if (_matcher && _delay_line && _decoders.audio) { - _decoders.audio->connect_audio (_delay_line); - _delay_line->connect_audio (_matcher); - _matcher->connect_audio (_gain); - _gain->connect_audio (_encoder); - } + _decoders.audio->connect_audio (_delay_line); + _delay_line->connect_audio (_matcher); + _matcher->connect_audio (_gain); + _gain->connect_audio (_encoder); } /** Run the decoder, passing its output to the encoder, until the decoder -- cgit v1.2.3 From 7a9a8229b57139ece3f9848910087310c06169c7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 6 Mar 2013 23:08:07 +0000 Subject: Try doing delay line by fiddling timestamps. Fix up confusion in A/B transcoder similar to that in standard one. --- src/lib/ab_transcoder.cc | 30 ++++++--------- src/lib/delay_line.cc | 67 ++++++++------------------------- src/lib/delay_line.h | 11 ++---- src/lib/transcoder.cc | 17 +++------ test/test.cc | 98 ------------------------------------------------ 5 files changed, 36 insertions(+), 187 deletions(-) (limited to 'src/lib/transcoder.cc') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 373549b57..3af32f988 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -58,12 +58,10 @@ ABTranscoder::ABTranscoder ( _da = decoder_factory (_film_a, o); _db = decoder_factory (_film_b, o); - if (_film_a->audio_stream()) { - shared_ptr st = _film_a->audio_stream(); - _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate())); - _delay_line.reset (new DelayLine (_film_a->log(), st->channels(), _film_a->audio_delay() * st->sample_rate() / 1000)); - _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain())); - } + shared_ptr st = _film_a->audio_stream(); + _matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate())); + _delay_line.reset (new DelayLine (_film_a->log(), _film_a->audio_delay() / 1000.0f)); + _gain.reset (new Gain (_film_a->log(), _film_a->audio_gain())); /* Set up the decoder to use the film's set streams */ _da.video->set_subtitle_stream (_film_a->subtitle_stream ()); @@ -73,20 +71,14 @@ ABTranscoder::ABTranscoder ( _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 { - /* Remove timestamp from the output of the combiner */ - _combiner->Video.connect (bind (&Encoder::process_video, _encoder, _1, _2, _3)); - } + _combiner->connect_video (_delay_line); + _delay_line->connect_video (_matcher); + _matcher->connect_video (_encoder); - if (_matcher && _delay_line) { - _da.audio->connect_audio (_delay_line); - _delay_line->connect_audio (_matcher); - _matcher->connect_audio (_gain); - _gain->connect_audio (_encoder); - } + _da.audio->connect_audio (_delay_line); + _delay_line->connect_audio (_matcher); + _matcher->connect_audio (_gain); + _gain->connect_audio (_encoder); } void diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index 84785cfc6..924a1f082 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -27,68 +27,31 @@ using std::min; using boost::shared_ptr; -/** @param channels Number of channels of audio. - * @param frames Delay in frames, +ve to move audio later. +/* @param seconds Delay in seconds, +ve to move audio later. */ -DelayLine::DelayLine (Log* log, int channels, int frames) +DelayLine::DelayLine (Log* log, double seconds) : Processor (log) - , _negative_delay_remaining (0) - , _frames (frames) + , _seconds (seconds) { - if (_frames > 0) { - /* We need a buffer to keep some data in */ - _buffers.reset (new AudioBuffers (channels, _frames)); - _buffers->make_silent (); - } else if (_frames < 0) { - /* We can do -ve delays just by chopping off - the start, so no buffer needed. - */ - _negative_delay_remaining = -_frames; - } + } -/* XXX: can we just get rid of all this and fiddle with the timestamp? */ void DelayLine::process_audio (shared_ptr data, double t) { - if (_buffers) { - /* We have some buffers, so we are moving the audio later */ - - /* Copy the input data */ - AudioBuffers input (*data.get ()); - - int to_do = data->frames (); - - /* Write some of our buffer to the output */ - int const from_buffer = min (to_do, _buffers->frames()); - data->copy_from (_buffers.get(), from_buffer, 0, 0); - to_do -= from_buffer; - - /* Write some of the input to the output */ - int const from_input = to_do; - data->copy_from (&input, from_input, 0, from_buffer); - - int const left_in_buffer = _buffers->frames() - from_buffer; - - /* Shuffle our buffer down */ - _buffers->move (from_buffer, 0, left_in_buffer); - - /* Copy remaining input data to our buffer */ - _buffers->copy_from (&input, input.frames() - from_input, from_input, left_in_buffer); - - } else { + if (_seconds > 0) { + t += _seconds; + } - /* Chop the initial data off until _negative_delay_remaining - is zero, then just pass data. - */ + Audio (data, t); +} - int const to_do = min (data->frames(), _negative_delay_remaining); - if (to_do) { - data->move (to_do, 0, data->frames() - to_do); - data->set_frames (data->frames() - to_do); - _negative_delay_remaining -= to_do; - } +void +DelayLine::process_video (boost::shared_ptr image, bool same, boost::shared_ptr sub, double t) +{ + if (_seconds < 0) { + t += _seconds; } - Audio (data, t); + Video (image, same, sub, t); } diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index 8c4a3953c..a52fb981c 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -20,18 +20,15 @@ #include #include "processor.h" -class AudioBuffers; - /** A delay line for audio */ -class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource +class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource, public TimedVideoSink, public TimedVideoSource { public: - DelayLine (Log* log, int channels, int frames); + DelayLine (Log* log, double); + void process_video (boost::shared_ptr, bool, boost::shared_ptr, double); void process_audio (boost::shared_ptr, double); private: - boost::shared_ptr _buffers; - int _negative_delay_remaining; ///< number of frames of negative delay that remain to emit - int _frames; + double _seconds; }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index ae88116a0..8e5e15e7f 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -57,14 +57,15 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< shared_ptr st = f->audio_stream(); _matcher.reset (new Matcher (f->log(), st->sample_rate(), f->source_frame_rate())); - _delay_line.reset (new DelayLine (f->log(), st->channels(), f->audio_delay() * st->sample_rate() / 1000)); + _delay_line.reset (new DelayLine (f->log(), f->audio_delay() / 1000.0f)); _gain.reset (new Gain (f->log(), f->audio_gain())); /* Set up the decoder to use the film's set streams */ _decoders.video->set_subtitle_stream (f->subtitle_stream ()); _decoders.audio->set_audio_stream (f->audio_stream ()); - _decoders.video->connect_video (_matcher); + _decoders.video->connect_video (_delay_line); + _delay_line->connect_video (_matcher); _matcher->connect_video (_encoder); _decoders.audio->connect_audio (_delay_line); @@ -107,14 +108,8 @@ Transcoder::go () throw; } - if (_delay_line) { - _delay_line->process_end (); - } - if (_matcher) { - _matcher->process_end (); - } - if (_gain) { - _gain->process_end (); - } + _delay_line->process_end (); + _matcher->process_end (); + _gain->process_end (); _encoder->process_end (); } diff --git a/test/test.cc b/test/test.cc index b2af8ab22..5e85e0dd5 100644 --- a/test/test.cc +++ b/test/test.cc @@ -28,7 +28,6 @@ #include "job_manager.h" #include "util.h" #include "exceptions.h" -#include "delay_line.h" #include "image.h" #include "log.h" #include "dcp_video_frame.h" @@ -251,103 +250,6 @@ public: void do_log (string) {} }; -void -do_positive_delay_line_test (int delay_length, int data_length) -{ - NullLog log; - - DelayLine d (&log, 6, delay_length); - shared_ptr data (new AudioBuffers (6, data_length)); - - int in = 0; - int out = 0; - int returned = 0; - int zeros = 0; - - for (int i = 0; i < 64; ++i) { - for (int j = 0; j < data_length; ++j) { - for (int c = 0; c < 6; ++c ) { - data->data(c)[j] = in; - ++in; - } - } - - /* This only works because the delay line modifies the parameter */ - /* XXX: timestamp is wrong */ - d.process_audio (data, 0); - returned += data->frames (); - - for (int j = 0; j < data->frames(); ++j) { - if (zeros < delay_length) { - for (int c = 0; c < 6; ++c) { - BOOST_CHECK_EQUAL (data->data(c)[j], 0); - } - ++zeros; - } else { - for (int c = 0; c < 6; ++c) { - BOOST_CHECK_EQUAL (data->data(c)[j], out); - ++out; - } - } - } - } - - BOOST_CHECK_EQUAL (returned, 64 * data_length); -} - -void -do_negative_delay_line_test (int delay_length, int data_length) -{ - NullLog log; - - DelayLine d (&log, 6, delay_length); - shared_ptr data (new AudioBuffers (6, data_length)); - - int in = 0; - int out = -delay_length * 6; - int returned = 0; - - for (int i = 0; i < 256; ++i) { - data->set_frames (data_length); - for (int j = 0; j < data_length; ++j) { - for (int c = 0; c < 6; ++c) { - data->data(c)[j] = in; - ++in; - } - } - - /* This only works because the delay line modifies the parameter */ - /* XXX: timestamp is wrong */ - d.process_audio (data, 0); - returned += data->frames (); - - for (int j = 0; j < data->frames(); ++j) { - for (int c = 0; c < 6; ++c) { - BOOST_CHECK_EQUAL (data->data(c)[j], out); - ++out; - } - } - } - - returned += -delay_length; - BOOST_CHECK_EQUAL (returned, 256 * data_length); -} - -BOOST_AUTO_TEST_CASE (delay_line_test) -{ - do_positive_delay_line_test (64, 128); - do_positive_delay_line_test (128, 64); - do_positive_delay_line_test (3, 512); - do_positive_delay_line_test (512, 3); - - do_positive_delay_line_test (0, 64); - - do_negative_delay_line_test (-64, 128); - do_negative_delay_line_test (-128, 64); - do_negative_delay_line_test (-3, 512); - do_negative_delay_line_test (-512, 3); -} - BOOST_AUTO_TEST_CASE (md5_digest_test) { string const t = md5_digest ("test/md5.test"); -- cgit v1.2.3 From 3f2365fcf3a1ffc50901eb2e4af246aa4c83e272 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 15 Apr 2013 16:24:03 +0100 Subject: Repair very bad merge. Mysterious. --- src/lib/ab_transcoder.cc | 4 ++-- src/lib/audio_decoder.h | 2 +- src/lib/audio_sink.h | 7 +++++++ src/lib/audio_source.cc | 6 ++++++ src/lib/audio_source.h | 12 ++++++++++++ src/lib/combiner.cc | 8 ++++---- src/lib/combiner.h | 6 +++--- src/lib/delay_line.cc | 4 ++-- src/lib/delay_line.h | 4 ++-- src/lib/matcher.cc | 2 +- src/lib/matcher.h | 6 +++--- src/lib/processor.h | 17 +++++++++++++++++ src/lib/sndfile_decoder.cc | 5 +++-- src/lib/transcoder.cc | 9 --------- src/lib/video_decoder.h | 2 +- src/lib/video_sink.h | 12 ++++++++++++ src/lib/video_source.cc | 6 ++++++ src/lib/video_source.h | 23 +++++++++++++++++++++-- 18 files changed, 103 insertions(+), 32 deletions(-) (limited to 'src/lib/transcoder.cc') diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 7db13afcc..6eef397c2 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -70,8 +70,8 @@ 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)); _combiner->connect_video (_delay_line); _delay_line->connect_video (_matcher); 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, DecodeOptions); diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h index 11d578a60..f34b24f88 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) = 0; }; +class TimedAudioSink +{ +public: + /** Call with some audio data */ + virtual void process_audio (boost::shared_ptr, 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 s) { Audio.connect (bind (&AudioSink::process_audio, s, _1)); } + +void +TimedAudioSource::connect_audio (shared_ptr 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); }; + +/** A class that emits audio data with timestamps */ +class TimedAudioSource +{ +public: + /** Emitted when some audio data is ready */ + boost::signals2::signal, double)> Audio; + + void connect_audio (boost::shared_ptr); +}; + #endif diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 12ce4a96e..006dd2697 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; Combiner::Combiner (shared_ptr log) - : VideoProcessor (log) + : TimedVideoProcessor (log) { } @@ -33,7 +33,7 @@ Combiner::Combiner (shared_ptr log) * @param image Frame image. */ void -Combiner::process_video (shared_ptr image, bool, shared_ptr) +Combiner::process_video (shared_ptr image, bool, shared_ptr, double t) { _image = image; } @@ -43,7 +43,7 @@ Combiner::process_video (shared_ptr image, bool, shared_ptr) * @param sub Subtitle (which will be put onto the whole frame) */ void -Combiner::process_video_b (shared_ptr image, bool, shared_ptr sub) +Combiner::process_video_b (shared_ptr image, bool, shared_ptr 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, bool, shared_ptr 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 68026eaff..a8f1fa804 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 TimedVideoProcessor { public: Combiner (boost::shared_ptr log); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); - void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); + void process_video_b (boost::shared_ptr i, bool, boost::shared_ptr s, double); private: /** The image that we are currently working on */ diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index c8e593a18..9e6baeba8 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -30,14 +30,14 @@ using boost::shared_ptr; /* @param seconds Delay in seconds, +ve to move audio later. */ DelayLine::DelayLine (shared_ptr log, double seconds) - : Processor (log) + : TimedAudioVideoProcessor (log) , _seconds (seconds) { } void -DelayLine::process_audio (shared_ptr data) +DelayLine::process_audio (shared_ptr data, double t) { if (_seconds > 0) { t += _seconds; diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index 7a8b11c69..90f1dcfa7 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -20,8 +20,8 @@ #include #include "processor.h" -/** A delay line for audio */ -class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource, public TimedVideoSink, public TimedVideoSource +/** A delay line */ +class DelayLine : public TimedAudioVideoProcessor { public: DelayLine (boost::shared_ptr log, double); diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc index 69d12e2c4..34ddc86d6 100644 --- a/src/lib/matcher.cc +++ b/src/lib/matcher.cc @@ -29,7 +29,7 @@ using std::list; using boost::shared_ptr; Matcher::Matcher (shared_ptr 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) diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 4ec0a3e96..f54aa4b6a 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 TimedAudioSink, public TimedVideoSink, public AudioSource, public VideoSource { public: Matcher (boost::shared_ptr log, int sample_rate, float frames_per_second); - void process_video (boost::shared_ptr i, bool, boost::shared_ptr s); - void process_audio (boost::shared_ptr); + void process_video (boost::shared_ptr i, bool, boost::shared_ptr s, double); + void process_audio (boost::shared_ptr, double); void process_end (); private: diff --git a/src/lib/processor.h b/src/lib/processor.h index 1ba396f2f..603239f8f 100644 --- a/src/lib/processor.h +++ b/src/lib/processor.h @@ -67,6 +67,15 @@ public: {} }; +class TimedAudioVideoProcessor : public Processor, public TimedVideoSource, public TimedVideoSink, public TimedAudioSource, public TimedAudioSink +{ +public: + TimedAudioVideoProcessor (boost::shared_ptr log) + : Processor (log) + {} +}; + + /** @class AudioProcessor * @brief A processor which handles just audio data. */ @@ -95,4 +104,12 @@ public: {} }; +class TimedVideoProcessor : public Processor, public TimedVideoSource, public TimedVideoSink +{ +public: + TimedVideoProcessor (boost::shared_ptr log) + : Processor (log) + {} +}; + #endif diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index 0e3e5e234..af59c049c 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -113,8 +113,8 @@ SndfileDecoder::pass () to what FFmpeg (and in particular the resampler) can cope with. */ sf_count_t const block = _audio_stream->sample_rate() / 2; - shared_ptr 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 +126,8 @@ SndfileDecoder::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/transcoder.cc b/src/lib/transcoder.cc index 8046080de..23fb5b788 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -63,18 +63,9 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< _decoders.video->set_subtitle_stream (f->subtitle_stream ()); _decoders.audio->set_audio_stream (f->audio_stream ()); -<<<<<<< HEAD _decoders.video->connect_video (_delay_line); _delay_line->connect_video (_matcher); _matcher->connect_video (_encoder); -======= - if (_matcher) { - _decoders.video->connect_video (_matcher); - _matcher->connect_video (_encoder); - } else { - _decoders.video->connect_video (_encoder); - } ->>>>>>> master _decoders.audio->connect_audio (_delay_line); _delay_line->connect_audio (_matcher); diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index f8612dff2..6e4fd48c0 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, DecodeOptions); 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 i, bool same, boost::shared_ptr 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 i, bool same, boost::shared_ptr 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 s) { Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3)); } + +void +TimedVideoSource::connect_video (shared_ptr 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); }; +/** @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, bool, boost::shared_ptr, double)> Video; + + void connect_video (boost::shared_ptr); +}; + #endif -- cgit v1.2.3