Try doing delay line by fiddling timestamps. Fix up confusion in A/B transcoder...
authorCarl Hetherington <cth@carlh.net>
Wed, 6 Mar 2013 23:08:07 +0000 (23:08 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 6 Mar 2013 23:08:07 +0000 (23:08 +0000)
src/lib/ab_transcoder.cc
src/lib/delay_line.cc
src/lib/delay_line.h
src/lib/transcoder.cc
test/test.cc

index 373549b574f29dd83426cb2d391db5c02457d070..3af32f988f3b8e263549b6d372b215ae556b393d 100644 (file)
@@ -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<AudioStream> 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<AudioStream> 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
index 84785cfc69780f33e13bad00992f61cf563f891b..924a1f082a7ccf2840a6163f693937307fbc26e6 100644 (file)
 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<AudioBuffers> 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> image, bool same, boost::shared_ptr<Subtitle> sub, double t)
+{
+       if (_seconds < 0) {
+               t += _seconds;
        }
 
-       Audio (data, t);
+       Video (image, same, sub, t);
 }
index 8c4a3953c7fcf78ae7a15d15d4cfdac956e49aeb..a52fb981c7c251cf31363a35b5a3caaa00b3e42c 100644 (file)
 #include <boost/shared_ptr.hpp>
 #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<Image>, bool, boost::shared_ptr<Subtitle>, double);
        void process_audio (boost::shared_ptr<AudioBuffers>, double);
 
 private:
-       boost::shared_ptr<AudioBuffers> _buffers;
-       int _negative_delay_remaining; ///< number of frames of negative delay that remain to emit
-       int _frames;
+       double _seconds;
 };
index ae88116a0452b2e723852fabbeadd281005ab11d..8e5e15e7f0a770c46376d96565ab6f333667c2a5 100644 (file)
@@ -57,14 +57,15 @@ Transcoder::Transcoder (shared_ptr<Film> f, DecodeOptions o, Job* j, shared_ptr<
 
        shared_ptr<AudioStream> 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 ();
 }
index b2af8ab22d25b6e4004bbc9abbb0f8a93af0d965..5e85e0dd5c1db76af0e0cd2919077075423f0c47 100644 (file)
@@ -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<AudioBuffers> 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<AudioBuffers> 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");