Reinstate subtitle speed-up patch 526fd6de4c80a7ac9614a1cb0209efff7b171cd5 but only...
authorCarl Hetherington <cth@carlh.net>
Mon, 26 Oct 2015 09:37:29 +0000 (09:37 +0000)
committerCarl Hetherington <cth@carlh.net>
Mon, 26 Oct 2015 09:37:29 +0000 (09:37 +0000)
23 files changed:
src/lib/audio_decoder_stream.cc
src/lib/dcp_decoder.cc
src/lib/dcp_decoder.h
src/lib/dcp_subtitle_decoder.cc
src/lib/dcp_subtitle_decoder.h
src/lib/decoder.h
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/image_decoder.cc
src/lib/image_decoder.h
src/lib/player.cc
src/lib/player.h
src/lib/sndfile_decoder.cc
src/lib/sndfile_decoder.h
src/lib/subrip_decoder.cc
src/lib/subrip_decoder.h
src/lib/subtitle_decoder.cc
src/lib/subtitle_decoder.h
src/lib/transcoder.cc
src/lib/video_decoder.cc
src/wx/subtitle_view.cc
test/audio_decoder_test.cc
test/dcp_subtitle_test.cc

index 274bf2d547e41ecb29a6d5d7b8abb451fe6da312..4fedf9291eea8e55515a187ae688dbfb437748e0 100644 (file)
@@ -87,7 +87,7 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
                /* Keep stuffing data into _decoded until we have enough data, or the subclass does not want to give us any more */
                while (
                        (_decoded.frame > frame || (_decoded.frame + _decoded.audio->frames()) < end) &&
-                       !_decoder->pass ()
+                       !_decoder->pass (Decoder::PASS_REASON_AUDIO, accurate)
                        )
                {}
 
@@ -95,7 +95,7 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
        } else {
                while (
                        _decoded.audio->frames() < length &&
-                       !_decoder->pass ()
+                       !_decoder->pass (Decoder::PASS_REASON_AUDIO, accurate)
                        )
                {}
 
index 21eb2f7ea48d116f828d9955ff93ca817687636f..04fffb9816f9642eb22a2bea1e09fb2adfbdfbb1 100644 (file)
@@ -59,7 +59,7 @@ DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, bool fast)
 }
 
 bool
-DCPDecoder::pass ()
+DCPDecoder::pass (PassReason reason, bool)
 {
        if (_reel == _reels.end () || !_dcp_content->can_be_played ()) {
                return true;
@@ -68,7 +68,7 @@ DCPDecoder::pass ()
        double const vfr = _dcp_content->video_frame_rate ();
        int64_t const frame = _next.frames_round (vfr);
 
-       if ((*_reel)->main_picture ()) {
+       if ((*_reel)->main_picture () && reason != PASS_REASON_SUBTITLE) {
                shared_ptr<dcp::PictureAsset> asset = (*_reel)->main_picture()->asset ();
                shared_ptr<dcp::MonoPictureAsset> mono = dynamic_pointer_cast<dcp::MonoPictureAsset> (asset);
                shared_ptr<dcp::StereoPictureAsset> stereo = dynamic_pointer_cast<dcp::StereoPictureAsset> (asset);
@@ -88,7 +88,7 @@ DCPDecoder::pass ()
                }
        }
 
-       if ((*_reel)->main_sound ()) {
+       if ((*_reel)->main_sound () && reason != PASS_REASON_SUBTITLE) {
                int64_t const entry_point = (*_reel)->main_sound()->entry_point ();
                shared_ptr<const dcp::SoundFrame> sf = (*_reel)->main_sound()->asset()->get_frame (entry_point + frame);
                uint8_t const * from = sf->data ();
index 6fdbd946af348dcd2f99a7d8306e5c8e6dabeff4..0db707160b88e6a9a736136e5b4f983fd5086771 100644 (file)
@@ -44,7 +44,7 @@ public:
 private:
        friend struct dcp_subtitle_within_dcp_test;
 
-       bool pass ();
+       bool pass (PassReason, bool accurate);
        void seek (ContentTime t, bool accurate);
 
        std::list<ContentTimePeriod> image_subtitles_during (ContentTimePeriod, bool starting) const;
index 1c6b973d683913722e4b6cecb2570bed205b0f21..1bcc7fcf17844926eb217095ecc559b7cfab4fbe 100644 (file)
@@ -47,7 +47,7 @@ DCPSubtitleDecoder::seek (ContentTime time, bool accurate)
 }
 
 bool
-DCPSubtitleDecoder::pass ()
+DCPSubtitleDecoder::pass (PassReason, bool)
 {
        if (_next == _subtitles.end ()) {
                return true;
index fb2213fa271d2f933d981d042ce268130aaf653f..1f53776228fcb7513fb0012f4f4c88c39d3c2843 100644 (file)
@@ -28,7 +28,7 @@ public:
        DCPSubtitleDecoder (boost::shared_ptr<const DCPSubtitleContent>);
 
 protected:
-       bool pass ();
+       bool pass (PassReason, bool accurate);
        void seek (ContentTime time, bool accurate);
 
 private:
index 8378373c6e0e29c8c4ed45943a30a6817651ed2e..9867b79b099a12466790c637ce78011a6867a830 100644 (file)
@@ -51,7 +51,13 @@ protected:
         */
        virtual void seek (ContentTime time, bool accurate) = 0;
 
-       virtual bool pass () = 0;
+       enum PassReason {
+               PASS_REASON_VIDEO,
+               PASS_REASON_AUDIO,
+               PASS_REASON_SUBTITLE
+       };
+
+       virtual bool pass (PassReason, bool accurate) = 0;
 };
 
 #endif
index 72a3d02b49f6f732827a649ab24d4e4815ce64bf..cc4bd34d464fefc64c8c87de2bdb891e4e3c8b6d 100644 (file)
@@ -89,7 +89,7 @@ FFmpegDecoder::flush ()
 }
 
 bool
-FFmpegDecoder::pass ()
+FFmpegDecoder::pass (PassReason reason, bool accurate)
 {
        int r = av_read_frame (_format_context, &_packet);
 
@@ -112,11 +112,11 @@ FFmpegDecoder::pass ()
        int const si = _packet.stream_index;
        shared_ptr<const FFmpegContent> fc = _ffmpeg_content;
 
-       if (si == _video_stream && !_ignore_video) {
+       if (si == _video_stream && !_ignore_video && (accurate || reason != PASS_REASON_SUBTITLE)) {
                decode_video_packet ();
        } else if (fc->subtitle_stream() && fc->subtitle_stream()->uses_index (_format_context, si)) {
                decode_subtitle_packet ();
-       } else {
+       } else if (reason != PASS_REASON_SUBTITLE) {
                decode_audio_packet ();
        }
 
index 5475be6122da98b51c4bb8414a837af46d0be087..dc0270cd0d4ba4433077e361b6b8d208d841b09e 100644 (file)
@@ -49,7 +49,7 @@ public:
 private:
        friend struct ::ffmpeg_pts_offset_test;
 
-       bool pass ();
+       bool pass (PassReason, bool accurate);
        void seek (ContentTime time, bool);
        void flush ();
 
index db7c5401fa3591c536fdf6083bf0a159e366e255..2291daecd7996f85e00ad9bdc7d6cc9a96e8be90 100644 (file)
@@ -43,7 +43,7 @@ ImageDecoder::ImageDecoder (shared_ptr<const ImageContent> c)
 }
 
 bool
-ImageDecoder::pass ()
+ImageDecoder::pass (PassReason, bool)
 {
        if (_video_position >= _image_content->video_length()) {
                return true;
index 4d96306a89c63775121f4e243da36ce2aa507372..e2de56acb9b1789f5e0e37a584dc30b88acc8625 100644 (file)
@@ -31,11 +31,10 @@ public:
        }
 
 private:
-       bool pass ();
+       bool pass (PassReason, bool);
        void seek (ContentTime, bool);
 
        boost::shared_ptr<const ImageContent> _image_content;
        boost::shared_ptr<ImageProxy> _image;
        Frame _video_position;
 };
-
index 116410046e5f0eaa3b5acfc9eddb8aee533d1b0b..b8eadf793ae3f54c516764efbbc91717df9d01f2 100644 (file)
@@ -357,7 +357,7 @@ Player::get_video (DCPTime time, bool accurate)
 
        /* Find subtitles for possible burn-in */
 
-       PlayerSubtitles ps = get_subtitles (time, DCPTime::from_frames (1, _film->video_frame_rate ()), false, true);
+       PlayerSubtitles ps = get_subtitles (time, DCPTime::from_frames (1, _film->video_frame_rate ()), false, true, accurate);
 
        list<PositionImage> sub_images;
 
@@ -619,7 +619,7 @@ Player::content_subtitle_to_dcp (shared_ptr<const Piece> piece, ContentTime t) c
  *  _always_burn_subtitles is true; in this case, all subtitles will be returned.
  */
 PlayerSubtitles
-Player::get_subtitles (DCPTime time, DCPTime length, bool starting, bool burnt)
+Player::get_subtitles (DCPTime time, DCPTime length, bool starting, bool burnt, bool accurate)
 {
        list<shared_ptr<Piece> > subs = overlaps<SubtitleContent> (time, time + length);
 
@@ -641,7 +641,7 @@ Player::get_subtitles (DCPTime time, DCPTime length, bool starting, bool burnt)
                /* XXX: this video_frame_rate() should be the rate that the subtitle content has been prepared for */
                ContentTime const to = from + ContentTime::from_frames (1, _film->video_frame_rate ());
 
-               list<ContentImageSubtitle> image = subtitle_decoder->get_image_subtitles (ContentTimePeriod (from, to), starting);
+               list<ContentImageSubtitle> image = subtitle_decoder->get_image_subtitles (ContentTimePeriod (from, to), starting, accurate);
                for (list<ContentImageSubtitle>::iterator i = image.begin(); i != image.end(); ++i) {
 
                        /* Apply content's subtitle offsets */
@@ -659,7 +659,7 @@ Player::get_subtitles (DCPTime time, DCPTime length, bool starting, bool burnt)
                        ps.image.push_back (i->sub);
                }
 
-               list<ContentTextSubtitle> text = subtitle_decoder->get_text_subtitles (ContentTimePeriod (from, to), starting);
+               list<ContentTextSubtitle> text = subtitle_decoder->get_text_subtitles (ContentTimePeriod (from, to), starting, accurate);
                BOOST_FOREACH (ContentTextSubtitle& ts, text) {
                        BOOST_FOREACH (dcp::SubtitleString s, ts.subs) {
                                s.set_h_position (s.h_position() + subtitle_content->subtitle_x_offset ());
index 3106a3477abef0cd760a607004e78effe00e5fb5..bfb21abba515c3e0fed011b006e7adc8fa0a14cd 100644 (file)
@@ -49,7 +49,7 @@ public:
 
        std::list<boost::shared_ptr<PlayerVideo> > get_video (DCPTime time, bool accurate);
        boost::shared_ptr<AudioBuffers> get_audio (DCPTime time, DCPTime length, bool accurate);
-       PlayerSubtitles get_subtitles (DCPTime time, DCPTime length, bool starting, bool burnt);
+       PlayerSubtitles get_subtitles (DCPTime time, DCPTime length, bool starting, bool burnt, bool accurate);
        std::list<boost::shared_ptr<Font> > get_subtitle_fonts ();
        std::list<ReferencedReelAsset> get_reel_assets ();
 
index 49633dd1fad2e503b345bf078fa4c56e454b52c1..ac01e0da87c99bf23fbc23da0b7ad4fc4a5eb4f9 100644 (file)
@@ -48,7 +48,7 @@ SndfileDecoder::~SndfileDecoder ()
 }
 
 bool
-SndfileDecoder::pass ()
+SndfileDecoder::pass (PassReason, bool)
 {
        if (_remaining == 0) {
                return true;
index da9016ee09a958c26211df60e4ae68b6a1d9620d..844d1cdc42818219e81e82a7cf1f04077851e6b6 100644 (file)
@@ -29,7 +29,7 @@ public:
        ~SndfileDecoder ();
 
 private:
-       bool pass ();
+       bool pass (PassReason, bool);
        void seek (ContentTime, bool);
 
        int64_t _done;
index 32d50d86b14e62ad44b0f28015799fea1ce1514b..26a7ebcae23634ce5837844b9477b2bedf54f101 100644 (file)
@@ -49,7 +49,7 @@ SubRipDecoder::seek (ContentTime time, bool accurate)
 }
 
 bool
-SubRipDecoder::pass ()
+SubRipDecoder::pass (PassReason, bool)
 {
        if (_next >= _subtitles.size ()) {
                return true;
index db8374c5c86fac05cbac154ca31329618caea02c..f76d04aebaa62243234849f9bc971bf06e3f6b26 100644 (file)
@@ -32,7 +32,7 @@ public:
 
 protected:
        void seek (ContentTime time, bool accurate);
-       bool pass ();
+       bool pass (PassReason, bool accurate);
 
 private:
        std::list<ContentTimePeriod> image_subtitles_during (ContentTimePeriod, bool starting) const;
index a7da626b7665fb6d1af02908d7aaccb1c358f7eb..454243b524d279b65eeaa7b57eacdc4f43cabab9 100644 (file)
@@ -56,7 +56,7 @@ SubtitleDecoder::text_subtitle (ContentTimePeriod period, list<dcp::SubtitleStri
 /** @param sp Full periods of subtitles that are showing or starting during the specified period */
 template <class T>
 list<T>
-SubtitleDecoder::get (list<T> const & subs, list<ContentTimePeriod> const & sp, ContentTimePeriod period, bool starting)
+SubtitleDecoder::get (list<T> const & subs, list<ContentTimePeriod> const & sp, ContentTimePeriod period, bool starting, bool accurate)
 {
        if (sp.empty ()) {
                /* Nothing in this period */
@@ -72,7 +72,7 @@ SubtitleDecoder::get (list<T> const & subs, list<ContentTimePeriod> const & sp,
         *  (a) give us what we want, or
         *  (b) hit the end of the decoder.
         */
-       while (!pass () && (subs.empty() || (subs.back().period().to < sp.back().to))) {}
+       while (!pass(PASS_REASON_SUBTITLE, accurate) && (subs.empty() || (subs.back().period().to < sp.back().to))) {}
 
        /* Now look for what we wanted in the data we have collected */
        /* XXX: inefficient */
@@ -105,15 +105,15 @@ SubtitleDecoder::get (list<T> const & subs, list<ContentTimePeriod> const & sp,
 }
 
 list<ContentTextSubtitle>
-SubtitleDecoder::get_text_subtitles (ContentTimePeriod period, bool starting)
+SubtitleDecoder::get_text_subtitles (ContentTimePeriod period, bool starting, bool accurate)
 {
-       return get<ContentTextSubtitle> (_decoded_text_subtitles, text_subtitles_during (period, starting), period, starting);
+       return get<ContentTextSubtitle> (_decoded_text_subtitles, text_subtitles_during (period, starting), period, starting, accurate);
 }
 
 list<ContentImageSubtitle>
-SubtitleDecoder::get_image_subtitles (ContentTimePeriod period, bool starting)
+SubtitleDecoder::get_image_subtitles (ContentTimePeriod period, bool starting, bool accurate)
 {
-       return get<ContentImageSubtitle> (_decoded_image_subtitles, image_subtitles_during (period, starting), period, starting);
+       return get<ContentImageSubtitle> (_decoded_image_subtitles, image_subtitles_during (period, starting), period, starting, accurate);
 }
 
 void
index d01c4e45b0ba5480567818d3f53809d1683fa325..dd9c024e6f9e1583a5af65d5350daabce3b852a9 100644 (file)
@@ -33,8 +33,8 @@ class SubtitleDecoder : public virtual Decoder
 public:
        SubtitleDecoder (boost::shared_ptr<const SubtitleContent>);
 
-       std::list<ContentImageSubtitle> get_image_subtitles (ContentTimePeriod period, bool starting);
-       std::list<ContentTextSubtitle> get_text_subtitles (ContentTimePeriod period, bool starting);
+       std::list<ContentImageSubtitle> get_image_subtitles (ContentTimePeriod period, bool starting, bool accurate);
+       std::list<ContentTextSubtitle> get_text_subtitles (ContentTimePeriod period, bool starting, bool accurate);
 
 protected:
        void seek (ContentTime, bool);
@@ -47,7 +47,7 @@ protected:
 
 private:
        template <class T>
-       std::list<T> get (std::list<T> const & subs, std::list<ContentTimePeriod> const & sp, ContentTimePeriod period, bool starting);
+       std::list<T> get (std::list<T> const & subs, std::list<ContentTimePeriod> const & sp, ContentTimePeriod period, bool starting, bool accurate);
 
        /** @param starting true if we want only subtitles that start during the period, otherwise
         *  we want subtitles that overlap the period.
index acff9c8965832a1af81739bffcd6376c38039e83..7eb3883ff452fce8ef7c1ffe8977d0f0abcf80a6 100644 (file)
@@ -91,7 +91,7 @@ Transcoder::go ()
                _writer->write (_player->get_audio (t, frame, true));
 
                if (non_burnt_subtitles) {
-                       _writer->write (_player->get_subtitles (t, frame, true, false));
+                       _writer->write (_player->get_subtitles (t, frame, true, false, true));
                }
        }
 
index 1c9a6374fa9dad584ee6c49abf53545b993fc7e4..fd5779a657f0304124a28ef27980a62a85a1945a 100644 (file)
@@ -98,7 +98,7 @@ VideoDecoder::get_video (Frame frame, bool accurate)
                                break;
                        }
 
-                       if (pass ()) {
+                       if (pass (PASS_REASON_VIDEO, accurate)) {
                                /* The decoder has nothing more for us */
                                break;
                        }
@@ -115,7 +115,7 @@ VideoDecoder::get_video (Frame frame, bool accurate)
                dec = decoded_video (frame);
        } else {
                /* Any frame will do: use the first one that comes out of pass() */
-               while (_decoded_video.empty() && !pass ()) {}
+               while (_decoded_video.empty() && !pass (PASS_REASON_VIDEO, accurate)) {}
                if (!_decoded_video.empty ()) {
                        dec.push_back (_decoded_video.front ());
                }
index 33ef7cfda14817326ca1de8a3f75011df7aa4026..632b209edf2feeebf22e9c11d4afd9f1e6ff5a6a 100644 (file)
@@ -65,7 +65,7 @@ SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<Film> film, shared_ptr<
                sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
        }
 
-       list<ContentTextSubtitle> subs = decoder->get_text_subtitles (ContentTimePeriod (ContentTime(), ContentTime::max ()), true);
+       list<ContentTextSubtitle> subs = decoder->get_text_subtitles (ContentTimePeriod (ContentTime(), ContentTime::max ()), true, true);
        FrameRateChange const frc = film->active_frame_rate_change (position);
        int n = 0;
        for (list<ContentTextSubtitle>::const_iterator i = subs.begin(); i != subs.end(); ++i) {
@@ -83,4 +83,3 @@ SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<Film> film, shared_ptr<
 
        SetSizerAndFit (sizer);
 }
-
index 44d0d60f416e664fa76faf9495b9e8601b4c4f1c..2c6794a7604f8fd45df29b88a8e4734533894d3e 100644 (file)
@@ -65,7 +65,7 @@ public:
                , _position (0)
        {}
 
-       bool pass ()
+       bool pass (PassReason, bool)
        {
                Frame const N = min (
                        Frame (2000),
index d7d55e9c06bae5a3ac471fd362e81ce6a49677cd..0e5f2d6ad2b894c4cea765f98d56a3bb15779282 100644 (file)
@@ -88,6 +88,7 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_within_dcp_test)
                        ContentTime::from_seconds (25),
                        ContentTime::from_seconds (26)
                        ),
+               true,
                true
                );