Set AudioDecoder::fast a different way.
authorCarl Hetherington <cth@carlh.net>
Wed, 22 Jun 2016 00:47:28 +0000 (01:47 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 22 Jun 2016 00:47:28 +0000 (01:47 +0100)
22 files changed:
src/lib/audio_decoder.cc
src/lib/audio_decoder.h
src/lib/audio_decoder_stream.cc
src/lib/audio_decoder_stream.h
src/lib/dcp_content.cc
src/lib/dcp_decoder.cc
src/lib/dcp_decoder.h
src/lib/decoder_factory.cc
src/lib/decoder_factory.h
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/player.cc
src/lib/resampler.cc
src/lib/resampler.h
src/wx/subtitle_panel.cc
test/audio_decoder_test.cc
test/dcp_subtitle_test.cc
test/ffmpeg_decoder_seek_test.cc
test/ffmpeg_decoder_sequential_test.cc
test/ffmpeg_pts_offset_test.cc
test/resampler_test.cc
test/seek_zero_test.cc

index 8c395cb89a0074aa171c3eb06b39c6bc4c00d508..4b89dc62053fe543e3527efbb1a5f78e4bc9b161 100644 (file)
@@ -31,12 +31,12 @@ using std::cout;
 using std::map;
 using boost::shared_ptr;
 
-AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, bool fast, shared_ptr<Log> log)
+AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, shared_ptr<Log> log)
        : _ignore (false)
-       , _fast (fast)
+       , _fast (false)
 {
        BOOST_FOREACH (AudioStreamPtr i, content->streams ()) {
-               _streams[i] = shared_ptr<AudioDecoderStream> (new AudioDecoderStream (content, i, parent, fast, log));
+               _streams[i] = shared_ptr<AudioDecoderStream> (new AudioDecoderStream (content, i, parent, log));
        }
 }
 
@@ -101,3 +101,11 @@ AudioDecoder::set_ignore ()
 {
        _ignore = true;
 }
+
+void
+AudioDecoder::set_fast ()
+{
+       for (map<AudioStreamPtr, shared_ptr<AudioDecoderStream> >::const_iterator i = _streams.begin(); i != _streams.end(); ++i) {
+               i->second->set_fast ();
+       }
+}
index fbb1ad4d45f8d9a0988c3706dcd46564df45a6ec..315cd94e49a34531023961a421784653d6c88802 100644 (file)
@@ -41,7 +41,7 @@ class Log;
 class AudioDecoder : public boost::enable_shared_from_this<AudioDecoder>
 {
 public:
-       AudioDecoder (Decoder* parent, boost::shared_ptr<const AudioContent>, bool fast, boost::shared_ptr<Log> log);
+       AudioDecoder (Decoder* parent, boost::shared_ptr<const AudioContent>, boost::shared_ptr<Log> log);
 
        /** Try to fetch some audio from a specific place in this content.
         *  @param frame Frame to start from (after resampling, if applicable)
@@ -52,10 +52,7 @@ public:
        ContentAudio get (AudioStreamPtr stream, Frame time, Frame length, bool accurate);
 
        void set_ignore ();
-
-       bool fast () const {
-               return _fast;
-       }
+       void set_fast ();
 
        void give (AudioStreamPtr stream, boost::shared_ptr<const AudioBuffers>, ContentTime);
        void flush ();
index 1bfc65871da4d2bdd962d0258a8d24e90b6f66f9..a254356ef0b790ead98aea5d7b67105bad940bf1 100644 (file)
@@ -40,14 +40,14 @@ using std::max;
 using boost::optional;
 using boost::shared_ptr;
 
-AudioDecoderStream::AudioDecoderStream (shared_ptr<const AudioContent> content, AudioStreamPtr stream, Decoder* decoder, bool fast, shared_ptr<Log> log)
+AudioDecoderStream::AudioDecoderStream (shared_ptr<const AudioContent> content, AudioStreamPtr stream, Decoder* decoder, shared_ptr<Log> log)
        : _content (content)
        , _stream (stream)
        , _decoder (decoder)
        , _log (log)
 {
        if (content->resampled_frame_rate() != _stream->frame_rate() && _stream->channels() > 0) {
-               _resampler.reset (new Resampler (_stream->frame_rate(), content->resampled_frame_rate(), _stream->channels (), fast));
+               _resampler.reset (new Resampler (_stream->frame_rate(), content->resampled_frame_rate(), _stream->channels ()));
        }
 
        reset_decoded ();
@@ -249,3 +249,11 @@ AudioDecoderStream::seek (ContentTime t, bool accurate)
                _seek_reference = t;
        }
 }
+
+void
+AudioDecoderStream::set_fast ()
+{
+       if (_resampler) {
+               _resampler->set_fast ();
+       }
+}
index 939a7d08b1a2f066800e041d4beb24b3a2a45d2b..a99464b894854071078992f26bd7b8772b9dfc9d 100644 (file)
@@ -35,12 +35,13 @@ class Decoder;
 class AudioDecoderStream
 {
 public:
-       AudioDecoderStream (boost::shared_ptr<const AudioContent>, AudioStreamPtr, Decoder* decoder, bool fast, boost::shared_ptr<Log> log);
+       AudioDecoderStream (boost::shared_ptr<const AudioContent>, AudioStreamPtr, Decoder* decoder, boost::shared_ptr<Log> log);
 
        ContentAudio get (Frame time, Frame length, bool accurate);
        void audio (boost::shared_ptr<const AudioBuffers>, ContentTime);
        void flush ();
        void seek (ContentTime time, bool accurate);
+       void set_fast ();
 
 private:
 
index 295f33b3c4560955ecac9d2d8201945153fadc8e..ca809df616443c0963e7f5c0dcadfc00dc6bc3ef 100644 (file)
@@ -332,7 +332,7 @@ DCPContent::reels () const
        list<DCPTimePeriod> p;
        scoped_ptr<DCPDecoder> decoder;
        try {
-               decoder.reset (new DCPDecoder (shared_from_this(), film()->log(), false));
+               decoder.reset (new DCPDecoder (shared_from_this(), film()->log()));
        } catch (...) {
                /* Could not load the DCP; guess reels */
                list<DCPTimePeriod> p;
@@ -403,7 +403,7 @@ DCPContent::can_reference_video (list<string>& why_not) const
 bool
 DCPContent::can_reference_audio (list<string>& why_not) const
 {
-        DCPDecoder decoder (shared_from_this(), film()->log(), false);
+        DCPDecoder decoder (shared_from_this(), film()->log());
         BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder.reels()) {
                 if (!i->main_sound()) {
                         why_not.push_back (_("The DCP does not have sound in all reels."));
@@ -417,7 +417,7 @@ DCPContent::can_reference_audio (list<string>& why_not) const
 bool
 DCPContent::can_reference_subtitle (list<string>& why_not) const
 {
-        DCPDecoder decoder (shared_from_this(), film()->log(), false);
+        DCPDecoder decoder (shared_from_this(), film()->log());
         BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder.reels()) {
                 if (!i->main_subtitle()) {
                         why_not.push_back (_("The DCP does not have subtitles in all reels."));
index c17b21a7fd9045dffe7af9157816a61a4b301ea5..7b4ef9fc7a6b6f668181b98c481b183bfcfb8032 100644 (file)
@@ -50,11 +50,11 @@ using std::cout;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 
-DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log, bool fast)
+DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log)
        : _dcp_content (c)
 {
        video.reset (new VideoDecoder (this, c, log));
-       audio.reset (new AudioDecoder (this, c->audio, fast, log));
+       audio.reset (new AudioDecoder (this, c->audio, log));
 
        subtitle.reset (
                new SubtitleDecoder (
index 7ad6fcbf7c53eff44193f4c5c289e424fd94c2b3..97a1847946a6f677985824893a9096b7ab2c9971 100644 (file)
@@ -38,7 +38,7 @@ struct dcp_subtitle_within_dcp_test;
 class DCPDecoder : public Decoder
 {
 public:
-       DCPDecoder (boost::shared_ptr<const DCPContent>, boost::shared_ptr<Log> log, bool fast);
+       DCPDecoder (boost::shared_ptr<const DCPContent>, boost::shared_ptr<Log> log);
 
        std::list<boost::shared_ptr<dcp::Reel> > reels () const {
                return _reels;
index dc01a043a56cf49aa1df7c0baf311be1aa6e9301..462a80eed74049d23ccfc2dced1e89220dfc4f1a 100644 (file)
@@ -37,16 +37,16 @@ using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 
 shared_ptr<Decoder>
-decoder_factory (shared_ptr<const Content> content, shared_ptr<Log> log, bool fast)
+decoder_factory (shared_ptr<const Content> content, shared_ptr<Log> log)
 {
        shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (content);
        if (fc) {
-               return shared_ptr<Decoder> (new FFmpegDecoder (fc, log, fast));
+               return shared_ptr<Decoder> (new FFmpegDecoder (fc, log));
        }
 
        shared_ptr<const DCPContent> dc = dynamic_pointer_cast<const DCPContent> (content);
        if (dc) {
-               return shared_ptr<Decoder> (new DCPDecoder (dc, log, fast));
+               return shared_ptr<Decoder> (new DCPDecoder (dc, log));
        }
 
        shared_ptr<const ImageContent> ic = dynamic_pointer_cast<const ImageContent> (content);
index 52a53afd2b34f129fb250087a429e5a149ddd5b8..43100d4d90782395f3f56e3a10798d11349875e9 100644 (file)
@@ -22,6 +22,5 @@ class ImageDecoder;
 
 extern boost::shared_ptr<Decoder> decoder_factory (
        boost::shared_ptr<const Content> content,
-       boost::shared_ptr<Log> log,
-       bool fast
+       boost::shared_ptr<Log> log
        );
index df6b7416b35a2fc521846ed91ec490e6faaef45d..164785c8368bb0fbffea1a28d468247df4eadf47 100644 (file)
@@ -75,7 +75,7 @@ using boost::is_any_of;
 using boost::split;
 using dcp::Size;
 
-FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log> log, bool fast)
+FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log> log)
        : FFmpeg (c)
        , _log (log)
 {
@@ -87,7 +87,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log>
        }
 
        if (c->audio) {
-               audio.reset (new AudioDecoder (this, c->audio, fast, log));
+               audio.reset (new AudioDecoder (this, c->audio, log));
        }
 
        if (c->subtitle) {
index 6be9f8b1cc79b63cf1042f598e2038f25fbe4b0c..76755c1fcc2d6e1a3c75b202d5b2d5dc6c266d1e 100644 (file)
@@ -44,7 +44,7 @@ struct ffmpeg_pts_offset_test;
 class FFmpegDecoder : public FFmpeg, public Decoder
 {
 public:
-       FFmpegDecoder (boost::shared_ptr<const FFmpegContent>, boost::shared_ptr<Log>, bool fast);
+       FFmpegDecoder (boost::shared_ptr<const FFmpegContent>, boost::shared_ptr<Log>);
 
 private:
        friend struct ::ffmpeg_pts_offset_test;
index 30313d39dd23bb57445cf43ff8a45f7b9c2d8b00..ba678dfeb92543fa0b4798c90c06d4ce845bef00 100644 (file)
@@ -123,7 +123,7 @@ Player::setup_pieces ()
                        continue;
                }
 
-               shared_ptr<Decoder> decoder = decoder_factory (i, _film->log(), _fast);
+               shared_ptr<Decoder> decoder = decoder_factory (i, _film->log());
                FrameRateChange frc (i->active_video_frame_rate(), _film->video_frame_rate());
 
                if (!decoder) {
@@ -139,6 +139,10 @@ Player::setup_pieces ()
                        decoder->audio->set_ignore ();
                }
 
+               if (decoder->audio && _fast) {
+                       decoder->audio->set_fast ();
+               }
+
                _pieces.push_back (shared_ptr<Piece> (new Piece (i, decoder, frc)));
        }
 
@@ -706,7 +710,7 @@ Player::get_reel_assets ()
 
                scoped_ptr<DCPDecoder> decoder;
                try {
-                       decoder.reset (new DCPDecoder (j, _film->log(), false));
+                       decoder.reset (new DCPDecoder (j, _film->log()));
                } catch (...) {
                        return a;
                }
index db5552d15ab3159b17510ca1295704d8806507a0..ff93d1609ae5e68590c3dcb76f8e2a337be216bf 100644 (file)
@@ -37,15 +37,14 @@ using boost::shared_ptr;
 /** @param in Input sampling rate (Hz)
  *  @param out Output sampling rate (Hz)
  *  @param channels Number of channels.
- *  @param fast true to be fast rather than good.
  */
-Resampler::Resampler (int in, int out, int channels, bool fast)
+Resampler::Resampler (int in, int out, int channels)
        : _in_rate (in)
        , _out_rate (out)
        , _channels (channels)
 {
        int error;
-       _src = src_new (fast ? SRC_LINEAR : SRC_SINC_BEST_QUALITY, _channels, &error);
+       _src = src_new (SRC_SINC_BEST_QUALITY, _channels, &error);
        if (!_src) {
                throw runtime_error (String::compose (N_("could not create sample-rate converter (%1)"), error));
        }
@@ -56,6 +55,17 @@ Resampler::~Resampler ()
        src_delete (_src);
 }
 
+void
+Resampler::set_fast ()
+{
+       src_delete (_src);
+       int error;
+       _src = src_new (SRC_LINEAR, _channels, &error);
+       if (!_src) {
+               throw runtime_error (String::compose (N_("could not create sample-rate converter (%1)"), error));
+       }
+}
+
 shared_ptr<const AudioBuffers>
 Resampler::run (shared_ptr<const AudioBuffers> in)
 {
index 5ce766f809612fa96904491660d4c2149cd85c70..afc28aefd01ce58a7ef2a1a431d29fff02ae4311 100644 (file)
@@ -28,11 +28,12 @@ class AudioBuffers;
 class Resampler : public boost::noncopyable
 {
 public:
-       Resampler (int, int, int, bool fast);
+       Resampler (int, int, int);
        ~Resampler ();
 
        boost::shared_ptr<const AudioBuffers> run (boost::shared_ptr<const AudioBuffers>);
        boost::shared_ptr<const AudioBuffers> flush ();
+       void set_fast ();
 
 private:
        SRC_STATE* _src;
index 4efc4eee426f6be0916751dac236ba95c724b5a6..933fcc6c171cba639432204926d4c6dcff3114cb 100644 (file)
@@ -386,7 +386,7 @@ SubtitlePanel::subtitle_view_clicked ()
        ContentList c = _parent->selected_subtitle ();
        DCPOMATIC_ASSERT (c.size() == 1);
 
-       shared_ptr<Decoder> decoder = decoder_factory (c.front(), _parent->film()->log(), false);
+       shared_ptr<Decoder> decoder = decoder_factory (c.front(), _parent->film()->log());
 
        if (decoder) {
                _subtitle_view = new SubtitleView (this, _parent->film(), decoder, c.front()->position ());
index 945773d1203fc24cda5b45432da94df5073a7d88..b71fd22c8705de9ab3c0e35ea4738b4b5af15ec1 100644 (file)
@@ -66,7 +66,7 @@ public:
                : _test_audio_content (content)
                , _position (0)
        {
-               audio.reset (new AudioDecoder (this, content->audio, false, log));
+               audio.reset (new AudioDecoder (this, content->audio, log));
        }
 
        bool pass (PassReason, bool)
index ef733d370d5bde31b15f0fa56c6e646a7171d024..d45ac603e4961c433fc2d72e8f40d938ed857105 100644 (file)
@@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_within_dcp_test)
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
-       shared_ptr<DCPDecoder> decoder (new DCPDecoder (content, film->log(), false));
+       shared_ptr<DCPDecoder> decoder (new DCPDecoder (content, film->log()));
 
        list<ContentTimePeriod> ctp = decoder->text_subtitles_during (
                ContentTimePeriod (
index 8a854b01b7e0d8671d5e7ee3f7646730e1eceb99..0e5b2963f89d60e6a004654413fb1acc8b87f546 100644 (file)
@@ -66,7 +66,7 @@ test (boost::filesystem::path file, vector<int> frames)
        film->examine_and_add_content (content);
        wait_for_jobs ();
        shared_ptr<Log> log (new NullLog);
-       shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (content, log, false));
+       shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (content, log));
 
        for (vector<int>::const_iterator i = frames.begin(); i != frames.end(); ++i) {
                check (decoder, *i);
index 6a27d698f5713997c0c0fd4d7e68caec77e8831c..6fa945f84269a5e94b4a5b5a3592b4ff3e66cbe2 100644 (file)
@@ -54,7 +54,7 @@ ffmpeg_decoder_sequential_test_one (boost::filesystem::path file, float fps, int
        film->examine_and_add_content (content);
        wait_for_jobs ();
        shared_ptr<Log> log (new NullLog);
-       shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (content, log, false));
+       shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (content, log));
 
        BOOST_REQUIRE (decoder->video->_content->video_frame_rate());
        BOOST_CHECK_CLOSE (decoder->video->_content->video_frame_rate().get(), fps, 0.01);
index 02ea0233d8e1bb4caa3efd188201c86f19219a8c..05c4e15c8dcdce222e14d1b62412c230d94f1aa4 100644 (file)
@@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                /* Sound == video so no offset required */
                content->_first_video = ContentTime ();
                content->ffmpeg_audio_streams().front()->first_audio = ContentTime ();
-               FFmpegDecoder decoder (content, film->log(), false);
+               FFmpegDecoder decoder (content, film->log());
                BOOST_CHECK_EQUAL (decoder._pts_offset, ContentTime ());
        }
 
@@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                /* Common offset should be removed */
                content->_first_video = ContentTime::from_seconds (600);
                content->ffmpeg_audio_streams().front()->first_audio = ContentTime::from_seconds (600);
-               FFmpegDecoder decoder (content, film->log(), false);
+               FFmpegDecoder decoder (content, film->log());
                BOOST_CHECK_EQUAL (decoder._pts_offset, ContentTime::from_seconds (-600));
        }
 
@@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                /* Video is on a frame boundary */
                content->_first_video = ContentTime::from_frames (1, 24);
                content->ffmpeg_audio_streams().front()->first_audio = ContentTime ();
-               FFmpegDecoder decoder (content, film->log(), false);
+               FFmpegDecoder decoder (content, film->log());
                BOOST_CHECK_EQUAL (decoder._pts_offset, ContentTime ());
        }
 
@@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                double const frame = 1.0 / 24.0;
                content->_first_video = ContentTime::from_seconds (frame + 0.0215);
                content->ffmpeg_audio_streams().front()->first_audio = ContentTime ();
-               FFmpegDecoder decoder (content, film->log(), false);
+               FFmpegDecoder decoder (content, film->log());
                BOOST_CHECK_CLOSE (decoder._pts_offset.seconds(), (frame - 0.0215), 0.00001);
        }
 
@@ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                double const frame = 1.0 / 24.0;
                content->_first_video = ContentTime::from_seconds (frame + 0.0215 + 4.1);
                content->ffmpeg_audio_streams().front()->first_audio = ContentTime::from_seconds (4.1);
-               FFmpegDecoder decoder (content, film->log(), false);
+               FFmpegDecoder decoder (content, film->log());
                BOOST_CHECK_CLOSE (decoder._pts_offset.seconds(), (frame - 0.0215) - 4.1, 0.1);
        }
 }
index fb4b98861c18afc65a421b3a075c4d9571a4eda1..6f102dd4c452d15dbd2645e580ae281070de0d87 100644 (file)
@@ -35,7 +35,7 @@ using boost::shared_ptr;
 static void
 resampler_test_one (int from, int to)
 {
-       Resampler resamp (from, to, 1, false);
+       Resampler resamp (from, to, 1);
 
        /* 3 hours */
        int64_t const N = int64_t (from) * 60 * 60 * 3;
index 05bf1b5bf4e519916cacb3bf263c45e1c7b72ebc..a176339e715515817aca7e80342785500967e374 100644 (file)
@@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE (seek_zero_test)
 
        Frame const first_frame = video_delay.round_up (content->active_video_frame_rate ()).frames_round (content->active_video_frame_rate ());
 
-       FFmpegDecoder decoder (content, film->log(), false);
+       FFmpegDecoder decoder (content, film->log());
        list<ContentVideo> a = decoder.video->get (first_frame, true);
        BOOST_CHECK (a.size() == 1);
        BOOST_CHECK_EQUAL (a.front().frame.index(), first_frame);