Put Film pointer into Decoder.
authorCarl Hetherington <cth@carlh.net>
Wed, 21 Nov 2018 02:45:30 +0000 (02:45 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 21 Nov 2018 02:45:30 +0000 (02:45 +0000)
20 files changed:
src/lib/dcp_content.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.cc
src/lib/decoder.h
src/lib/decoder_factory.cc
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/string_text_file_decoder.cc
src/lib/string_text_file_decoder.h
src/lib/video_mxf_decoder.cc
src/lib/video_mxf_decoder.h
src/wx/text_view.cc
test/dcp_subtitle_test.cc
test/ffmpeg_decoder_seek_test.cc

index 0bd28a9..62284e4 100644 (file)
@@ -612,7 +612,7 @@ DCPContent::can_reference_audio (shared_ptr<const Film> film, string& why_not) c
 {
        shared_ptr<DCPDecoder> decoder;
        try {
-               decoder.reset (new DCPDecoder (shared_from_this(), false));
+               decoder.reset (new DCPDecoder (film, shared_from_this(), false));
        } catch (dcp::DCPReadError) {
                /* We couldn't read the DCP, so it's probably missing */
                return false;
@@ -647,8 +647,9 @@ DCPContent::can_reference_text (shared_ptr<const Film> film, TextType type, stri
 {
        shared_ptr<DCPDecoder> decoder;
        try {
-               decoder.reset (new DCPDecoder (shared_from_this(), false));
+               decoder.reset (new DCPDecoder (film, shared_from_this(), false));
        } catch (dcp::DCPReadError) {
+
                /* We couldn't read the DCP, so it's probably missing */
                return false;
        } catch (dcp::KDMDecryptionError) {
index a67b244..1098bb8 100644 (file)
@@ -55,8 +55,9 @@ using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 using boost::optional;
 
-DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, bool fast)
+DCPDecoder::DCPDecoder (shared_ptr<const Film> film, shared_ptr<const DCPContent> c, bool fast)
        : DCP (c)
+       , Decoder (film)
        , _decode_referenced (false)
 {
        if (c->video) {
@@ -101,13 +102,13 @@ DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, bool fast)
 
 
 bool
-DCPDecoder::pass (shared_ptr<const Film> film)
+DCPDecoder::pass ()
 {
        if (_reel == _reels.end () || !_dcp_content->can_be_played ()) {
                return true;
        }
 
-       double const vfr = _dcp_content->active_video_frame_rate (film);
+       double const vfr = _dcp_content->active_video_frame_rate (film());
 
        /* Frame within the (played part of the) reel that is coming up next */
        int64_t const frame = _next.frames_round (vfr);
@@ -118,13 +119,13 @@ DCPDecoder::pass (shared_ptr<const Film> film)
        /* We must emit texts first as when we emit the video for this frame
           it will expect already to have the texts.
        */
-       pass_texts (film, _next, picture_asset->size());
+       pass_texts (_next, picture_asset->size());
 
        if ((_mono_reader || _stereo_reader) && (_decode_referenced || !_dcp_content->reference_video())) {
                int64_t const entry_point = (*_reel)->main_picture()->entry_point ();
                if (_mono_reader) {
                        video->emit (
-                               film,
+                               film(),
                                shared_ptr<ImageProxy> (
                                        new J2KImageProxy (
                                                _mono_reader->get_frame (entry_point + frame),
@@ -137,7 +138,7 @@ DCPDecoder::pass (shared_ptr<const Film> film)
                                );
                } else {
                        video->emit (
-                               film,
+                               film(),
                                shared_ptr<ImageProxy> (
                                        new J2KImageProxy (
                                                _stereo_reader->get_frame (entry_point + frame),
@@ -151,7 +152,7 @@ DCPDecoder::pass (shared_ptr<const Film> film)
                                );
 
                        video->emit (
-                               film,
+                               film(),
                                shared_ptr<ImageProxy> (
                                        new J2KImageProxy (
                                                _stereo_reader->get_frame (entry_point + frame),
@@ -182,7 +183,7 @@ DCPDecoder::pass (shared_ptr<const Film> film)
                        }
                }
 
-               audio->emit (film, _dcp_content->audio->stream(), data, ContentTime::from_frames (_offset, vfr) + _next);
+               audio->emit (film(), _dcp_content->audio->stream(), data, ContentTime::from_frames (_offset, vfr) + _next);
        }
 
        _next += ContentTime::from_frames (1, vfr);
@@ -198,13 +199,12 @@ DCPDecoder::pass (shared_ptr<const Film> film)
 }
 
 void
-DCPDecoder::pass_texts (shared_ptr<const Film> film, ContentTime next, dcp::Size size)
+DCPDecoder::pass_texts (ContentTime next, dcp::Size size)
 {
        list<shared_ptr<TextDecoder> >::const_iterator decoder = text.begin ();
        if ((*_reel)->main_subtitle()) {
                DCPOMATIC_ASSERT (decoder != text.end ());
                pass_texts (
-                       film,
                        next,
                        (*_reel)->main_subtitle()->asset(),
                        _dcp_content->reference_text(TEXT_OPEN_SUBTITLE),
@@ -217,7 +217,7 @@ DCPDecoder::pass_texts (shared_ptr<const Film> film, ContentTime next, dcp::Size
        BOOST_FOREACH (shared_ptr<dcp::ReelClosedCaptionAsset> i, (*_reel)->closed_captions()) {
                DCPOMATIC_ASSERT (decoder != text.end ());
                pass_texts (
-                       film, next, i->asset(), _dcp_content->reference_text(TEXT_CLOSED_CAPTION), i->entry_point(), *decoder, size
+                       next, i->asset(), _dcp_content->reference_text(TEXT_CLOSED_CAPTION), i->entry_point(), *decoder, size
                        );
                ++decoder;
        }
@@ -225,10 +225,10 @@ DCPDecoder::pass_texts (shared_ptr<const Film> film, ContentTime next, dcp::Size
 
 void
 DCPDecoder::pass_texts (
-       shared_ptr<const Film> film, ContentTime next, shared_ptr<dcp::SubtitleAsset> asset, bool reference, int64_t entry_point, shared_ptr<TextDecoder> decoder, dcp::Size size
+       ContentTime next, shared_ptr<dcp::SubtitleAsset> asset, bool reference, int64_t entry_point, shared_ptr<TextDecoder> decoder, dcp::Size size
        )
 {
-       double const vfr = _dcp_content->active_video_frame_rate (film);
+       double const vfr = _dcp_content->active_video_frame_rate (film());
        /* Frame within the (played part of the) reel that is coming up next */
        int64_t const frame = next.frames_round (vfr);
 
@@ -359,13 +359,13 @@ DCPDecoder::get_readers ()
 }
 
 void
-DCPDecoder::seek (shared_ptr<const Film> film, ContentTime t, bool accurate)
+DCPDecoder::seek (ContentTime t, bool accurate)
 {
        if (!_dcp_content->can_be_played ()) {
                return;
        }
 
-       Decoder::seek (film, t, accurate);
+       Decoder::seek (t, accurate);
 
        _reel = _reels.begin ();
        _offset = 0;
@@ -382,8 +382,8 @@ DCPDecoder::seek (shared_ptr<const Film> film, ContentTime t, bool accurate)
 
        /* Seek to pre-roll position */
 
-       while (_reel != _reels.end() && pre >= ContentTime::from_frames ((*_reel)->main_picture()->duration(), _dcp_content->active_video_frame_rate(film))) {
-               ContentTime rd = ContentTime::from_frames ((*_reel)->main_picture()->duration(), _dcp_content->active_video_frame_rate(film));
+       while (_reel != _reels.end() && pre >= ContentTime::from_frames ((*_reel)->main_picture()->duration(), _dcp_content->active_video_frame_rate(film()))) {
+               ContentTime rd = ContentTime::from_frames ((*_reel)->main_picture()->duration(), _dcp_content->active_video_frame_rate(film()));
                pre -= rd;
                t -= rd;
                next_reel ();
@@ -391,16 +391,16 @@ DCPDecoder::seek (shared_ptr<const Film> film, ContentTime t, bool accurate)
 
        /* Pass texts in the pre-roll */
 
-       double const vfr = _dcp_content->active_video_frame_rate (film);
+       double const vfr = _dcp_content->active_video_frame_rate (film());
        for (int i = 0; i < pre_roll_seconds * vfr; ++i) {
-               pass_texts (film, pre, (*_reel)->main_picture()->asset()->size());
+               pass_texts (pre, (*_reel)->main_picture()->asset()->size());
                pre += ContentTime::from_frames (1, vfr);
        }
 
        /* Seek to correct position */
 
-       while (_reel != _reels.end() && t >= ContentTime::from_frames ((*_reel)->main_picture()->duration(), _dcp_content->active_video_frame_rate(film))) {
-               t -= ContentTime::from_frames ((*_reel)->main_picture()->duration(), _dcp_content->active_video_frame_rate(film));
+       while (_reel != _reels.end() && t >= ContentTime::from_frames ((*_reel)->main_picture()->duration(), _dcp_content->active_video_frame_rate(film()))) {
+               t -= ContentTime::from_frames ((*_reel)->main_picture()->duration(), _dcp_content->active_video_frame_rate(film()));
                next_reel ();
        }
 
index d3c5c57..4068696 100644 (file)
@@ -40,7 +40,7 @@ struct dcp_subtitle_within_dcp_test;
 class DCPDecoder : public DCP, public Decoder
 {
 public:
-       DCPDecoder (boost::shared_ptr<const DCPContent>, bool fast);
+       DCPDecoder (boost::shared_ptr<const Film> film, boost::shared_ptr<const DCPContent>, bool fast);
 
        std::list<boost::shared_ptr<dcp::Reel> > reels () const {
                return _reels;
@@ -49,17 +49,16 @@ public:
        void set_decode_referenced (bool r);
        void set_forced_reduction (boost::optional<int> reduction);
 
-       bool pass (boost::shared_ptr<const Film> film);
-       void seek (boost::shared_ptr<const Film> film, ContentTime t, bool accurate);
+       bool pass ();
+       void seek (ContentTime t, bool accurate);
 
 private:
        friend struct dcp_subtitle_within_dcp_test;
 
        void next_reel ();
        void get_readers ();
-       void pass_texts (boost::shared_ptr<const Film> film, ContentTime next, dcp::Size size);
+       void pass_texts (ContentTime next, dcp::Size size);
        void pass_texts (
-               boost::shared_ptr<const Film> film,
                ContentTime next,
                boost::shared_ptr<dcp::SubtitleAsset> asset,
                bool reference,
index 07e879d..6c95b8b 100644 (file)
@@ -29,7 +29,8 @@ using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 using boost::bind;
 
-DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr<const DCPSubtitleContent> content)
+DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr<const Film> film, shared_ptr<const DCPSubtitleContent> content)
+       : Decoder (film)
 {
        shared_ptr<dcp::SubtitleAsset> c (load (content->path (0)));
        _subtitles = c->subtitles ();
@@ -43,9 +44,9 @@ DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr<const DCPSubtitleContent> con
 }
 
 void
-DCPSubtitleDecoder::seek (shared_ptr<const Film> film, ContentTime time, bool accurate)
+DCPSubtitleDecoder::seek (ContentTime time, bool accurate)
 {
-       Decoder::seek (film, time, accurate);
+       Decoder::seek (time, accurate);
 
        _next = _subtitles.begin ();
        list<shared_ptr<dcp::Subtitle> >::const_iterator i = _subtitles.begin ();
@@ -55,7 +56,7 @@ DCPSubtitleDecoder::seek (shared_ptr<const Film> film, ContentTime time, bool ac
 }
 
 bool
-DCPSubtitleDecoder::pass (shared_ptr<const Film>)
+DCPSubtitleDecoder::pass ()
 {
        if (_next == _subtitles.end ()) {
                return true;
index 7e83224..e553392 100644 (file)
@@ -26,10 +26,10 @@ class DCPSubtitleContent;
 class DCPSubtitleDecoder : public DCPSubtitle, public Decoder
 {
 public:
-       DCPSubtitleDecoder (boost::shared_ptr<const DCPSubtitleContent>);
+       DCPSubtitleDecoder (boost::shared_ptr<const Film> film, boost::shared_ptr<const DCPSubtitleContent>);
 
-       bool pass (boost::shared_ptr<const Film> film);
-       void seek (boost::shared_ptr<const Film> film, ContentTime time, bool accurate);
+       bool pass ();
+       void seek (ContentTime time, bool accurate);
 
 private:
        ContentTimePeriod content_time_period (boost::shared_ptr<dcp::Subtitle> s) const;
index fb7663f..52e8c04 100644 (file)
 using std::cout;
 using boost::optional;
 using boost::shared_ptr;
+using boost::weak_ptr;
+
+Decoder::Decoder (weak_ptr<const Film> film)
+       : _film (film)
+{
+
+}
 
 /** @return Earliest time of content that the next pass() will emit */
 ContentTime
-Decoder::position (shared_ptr<const Film> film) const
+Decoder::position () const
 {
        optional<ContentTime> pos;
+       shared_ptr<const Film> f = film();
 
-       if (video && !video->ignore() && (!pos || video->position(film) < *pos)) {
-               pos = video->position(film);
+       if (video && !video->ignore() && (!pos || video->position(f) < *pos)) {
+               pos = video->position(f);
        }
 
-       if (audio && !audio->ignore() && (!pos || audio->position(film) < *pos)) {
-               pos = audio->position(film);
+       if (audio && !audio->ignore() && (!pos || audio->position(f) < *pos)) {
+               pos = audio->position(f);
        }
 
        BOOST_FOREACH (shared_ptr<TextDecoder> i, text) {
-               if (!i->ignore() && (!pos || i->position(film) < *pos)) {
-                       pos = i->position(film);
+               if (!i->ignore() && (!pos || i->position(f) < *pos)) {
+                       pos = i->position(f);
                }
        }
 
@@ -53,7 +61,7 @@ Decoder::position (shared_ptr<const Film> film) const
 }
 
 void
-Decoder::seek (shared_ptr<const Film>, ContentTime, bool)
+Decoder::seek (ContentTime, bool)
 {
        if (video) {
                video->seek ();
@@ -75,3 +83,11 @@ Decoder::only_text () const
        }
        return text.front ();
 }
+
+shared_ptr<const Film>
+Decoder::film () const
+{
+       shared_ptr<const Film> f = _film.lock ();
+       DCPOMATIC_ASSERT (f);
+       return f;
+}
index a8a67ee..d610f87 100644 (file)
@@ -26,6 +26,7 @@
 #define DCPOMATIC_DECODER_H
 
 #include "types.h"
+#include "film.h"
 #include "dcpomatic_time.h"
 #include <boost/utility.hpp>
 
@@ -34,7 +35,6 @@ class VideoDecoder;
 class AudioDecoder;
 class TextDecoder;
 class DecoderPart;
-class Film;
 
 /** @class Decoder.
  *  @brief Parent class for decoders of content.
@@ -42,6 +42,7 @@ class Film;
 class Decoder : public boost::noncopyable
 {
 public:
+       Decoder (boost::weak_ptr<const Film> film);
        virtual ~Decoder () {}
 
        boost::shared_ptr<VideoDecoder> video;
@@ -53,10 +54,16 @@ public:
        /** Do some decoding and perhaps emit video, audio or subtitle data.
         *  @return true if this decoder will emit no more data unless a seek() happens.
         */
-       virtual bool pass (boost::shared_ptr<const Film> film) = 0;
-       virtual void seek (boost::shared_ptr<const Film> film, ContentTime time, bool accurate);
+       virtual bool pass () = 0;
+       virtual void seek (ContentTime time, bool accurate);
 
-       ContentTime position (boost::shared_ptr<const Film> film) const;
+       ContentTime position () const;
+
+protected:
+       boost::shared_ptr<const Film> film () const;
+
+private:
+       boost::weak_ptr<const Film> _film;
 };
 
 #endif
index b3e16a3..4b2a594 100644 (file)
@@ -47,7 +47,7 @@ decoder_factory (shared_ptr<const Film> film, shared_ptr<const Content> content,
        shared_ptr<const DCPContent> dc = dynamic_pointer_cast<const DCPContent> (content);
        if (dc) {
                try {
-                       return shared_ptr<Decoder> (new DCPDecoder(dc, fast));
+                       return shared_ptr<Decoder> (new DCPDecoder(film, dc, fast));
                } catch (KDMError& e) {
                        /* This will be found and reported to the user when the content is examined */
                        return shared_ptr<Decoder>();
@@ -56,22 +56,22 @@ decoder_factory (shared_ptr<const Film> film, shared_ptr<const Content> content,
 
        shared_ptr<const ImageContent> ic = dynamic_pointer_cast<const ImageContent> (content);
        if (ic) {
-               return shared_ptr<Decoder> (new ImageDecoder(ic));
+               return shared_ptr<Decoder> (new ImageDecoder(film, ic));
        }
 
        shared_ptr<const StringTextFileContent> rc = dynamic_pointer_cast<const StringTextFileContent> (content);
        if (rc) {
-               return shared_ptr<Decoder> (new StringTextFileDecoder(rc));
+               return shared_ptr<Decoder> (new StringTextFileDecoder(film, rc));
        }
 
        shared_ptr<const DCPSubtitleContent> dsc = dynamic_pointer_cast<const DCPSubtitleContent> (content);
        if (dsc) {
-               return shared_ptr<Decoder> (new DCPSubtitleDecoder(dsc));
+               return shared_ptr<Decoder> (new DCPSubtitleDecoder(film, dsc));
        }
 
        shared_ptr<const VideoMXFContent> vmc = dynamic_pointer_cast<const VideoMXFContent> (content);
        if (vmc) {
-               return shared_ptr<Decoder> (new VideoMXFDecoder(vmc));
+               return shared_ptr<Decoder> (new VideoMXFDecoder(film, vmc));
        }
 
        return shared_ptr<Decoder> ();
index 0e40f12..fbc0ee4 100644 (file)
@@ -80,6 +80,7 @@ using dcp::Size;
 
 FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> film, shared_ptr<const FFmpegContent> c, bool fast)
        : FFmpeg (c)
+       , Decoder (film)
        , _have_current_subtitle (false)
 {
        if (c->video) {
@@ -105,7 +106,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> film, shared_ptr<const FFmp
 }
 
 void
-FFmpegDecoder::flush (shared_ptr<const Film> film)
+FFmpegDecoder::flush ()
 {
        /* Get any remaining frames */
 
@@ -114,29 +115,29 @@ FFmpegDecoder::flush (shared_ptr<const Film> film)
 
        /* XXX: should we reset _packet.data and size after each *_decode_* call? */
 
-       while (video && decode_video_packet(film)) {}
+       while (video && decode_video_packet()) {}
 
        if (audio) {
-               decode_audio_packet (film);
+               decode_audio_packet ();
        }
 
        /* Make sure all streams are the same length and round up to the next video frame */
 
-       FrameRateChange const frc = film->active_frame_rate_change(_ffmpeg_content->position());
-       ContentTime full_length (_ffmpeg_content->full_length(film), frc);
+       FrameRateChange const frc = film()->active_frame_rate_change(_ffmpeg_content->position());
+       ContentTime full_length (_ffmpeg_content->full_length(film()), frc);
        full_length = full_length.ceil (frc.source);
        if (video) {
                double const vfr = _ffmpeg_content->video_frame_rate().get();
                Frame const f = full_length.frames_round (vfr);
-               Frame v = video->position(film).frames_round (vfr) + 1;
+               Frame v = video->position(film()).frames_round(vfr) + 1;
                while (v < f) {
-                       video->emit (film, shared_ptr<const ImageProxy> (new RawImageProxy (_black_image)), v);
+                       video->emit (film(), shared_ptr<const ImageProxy> (new RawImageProxy (_black_image)), v);
                        ++v;
                }
        }
 
        BOOST_FOREACH (shared_ptr<FFmpegAudioStream> i, _ffmpeg_content->ffmpeg_audio_streams ()) {
-               ContentTime a = audio->stream_position(film, i);
+               ContentTime a = audio->stream_position(film(), i);
                /* Unfortunately if a is 0 that really means that we don't know the stream position since
                   there has been no data on it since the last seek.  In this case we'll just do nothing
                   here.  I'm not sure if that's the right idea.
@@ -146,7 +147,7 @@ FFmpegDecoder::flush (shared_ptr<const Film> film)
                                ContentTime to_do = min (full_length - a, ContentTime::from_seconds (0.1));
                                shared_ptr<AudioBuffers> silence (new AudioBuffers (i->channels(), to_do.frames_ceil (i->frame_rate())));
                                silence->make_silent ();
-                               audio->emit (film, i, silence, a);
+                               audio->emit (film(), i, silence, a);
                                a += to_do;
                        }
                }
@@ -158,7 +159,7 @@ FFmpegDecoder::flush (shared_ptr<const Film> film)
 }
 
 bool
-FFmpegDecoder::pass (shared_ptr<const Film> film)
+FFmpegDecoder::pass ()
 {
        int r = av_read_frame (_format_context, &_packet);
 
@@ -174,7 +175,7 @@ FFmpegDecoder::pass (shared_ptr<const Film> film)
                        LOG_ERROR (N_("error on av_read_frame (%1) (%2)"), &buf[0], r);
                }
 
-               flush (film);
+               flush ();
                return true;
        }
 
@@ -182,11 +183,11 @@ FFmpegDecoder::pass (shared_ptr<const Film> film)
        shared_ptr<const FFmpegContent> fc = _ffmpeg_content;
 
        if (_video_stream && si == _video_stream.get() && !video->ignore()) {
-               decode_video_packet (film);
+               decode_video_packet ();
        } else if (fc->subtitle_stream() && fc->subtitle_stream()->uses_index(_format_context, si) && !only_text()->ignore()) {
                decode_subtitle_packet ();
        } else {
-               decode_audio_packet (film);
+               decode_audio_packet ();
        }
 
        av_packet_unref (&_packet);
@@ -340,9 +341,9 @@ FFmpegDecoder::bytes_per_audio_sample (shared_ptr<FFmpegAudioStream> stream) con
 }
 
 void
-FFmpegDecoder::seek (shared_ptr<const Film> film, ContentTime time, bool accurate)
+FFmpegDecoder::seek (ContentTime time, bool accurate)
 {
-       Decoder::seek (film, time, accurate);
+       Decoder::seek (time, accurate);
 
        /* If we are doing an `accurate' seek, we need to use pre-roll, as
           we don't really know what the seek will give us.
@@ -395,7 +396,7 @@ FFmpegDecoder::seek (shared_ptr<const Film> film, ContentTime time, bool accurat
 }
 
 void
-FFmpegDecoder::decode_audio_packet (shared_ptr<const Film> film)
+FFmpegDecoder::decode_audio_packet ()
 {
        /* Audio packets can contain multiple frames, so we may have to call avcodec_decode_audio4
           several times.
@@ -478,7 +479,7 @@ FFmpegDecoder::decode_audio_packet (shared_ptr<const Film> film)
 
                        /* Give this data provided there is some, and its time is sane */
                        if (ct >= ContentTime() && data->frames() > 0) {
-                               audio->emit (film, *stream, data, ct);
+                               audio->emit (film(), *stream, data, ct);
                        }
                }
 
@@ -488,7 +489,7 @@ FFmpegDecoder::decode_audio_packet (shared_ptr<const Film> film)
 }
 
 bool
-FFmpegDecoder::decode_video_packet (shared_ptr<const Film> film)
+FFmpegDecoder::decode_video_packet ()
 {
        DCPOMATIC_ASSERT (_video_stream);
 
@@ -526,9 +527,9 @@ FFmpegDecoder::decode_video_packet (shared_ptr<const Film> film)
                        double const pts = i->second * av_q2d (_format_context->streams[_video_stream.get()]->time_base) + _pts_offset.seconds ();
 
                        video->emit (
-                               film,
+                               film(),
                                shared_ptr<ImageProxy> (new RawImageProxy (image)),
-                               llrint(pts * _ffmpeg_content->active_video_frame_rate(film))
+                               llrint(pts * _ffmpeg_content->active_video_frame_rate(film()))
                                );
                } else {
                        LOG_WARNING_NC ("Dropping frame without PTS");
index 408ce30..640229f 100644 (file)
@@ -47,19 +47,19 @@ class FFmpegDecoder : public FFmpeg, public Decoder
 public:
        FFmpegDecoder (boost::shared_ptr<const Film> film, boost::shared_ptr<const FFmpegContent>, bool fast);
 
-       bool pass (boost::shared_ptr<const Film> film);
-       void seek (boost::shared_ptr<const Film> film, ContentTime time, bool);
+       bool pass ();
+       void seek (ContentTime time, bool);
 
 private:
        friend struct ::ffmpeg_pts_offset_test;
 
-       void flush (boost::shared_ptr<const Film> film);
+       void flush ();
 
        AVSampleFormat audio_sample_format (boost::shared_ptr<FFmpegAudioStream> stream) const;
        int bytes_per_audio_sample (boost::shared_ptr<FFmpegAudioStream> stream) const;
 
-       bool decode_video_packet (boost::shared_ptr<const Film> film);
-       void decode_audio_packet (boost::shared_ptr<const Film> film);
+       bool decode_video_packet ();
+       void decode_audio_packet ();
        void decode_subtitle_packet ();
 
        void decode_bitmap_subtitle (AVSubtitleRect const * rect, ContentTime from);
index ce8843b..a9e473f 100644 (file)
@@ -36,15 +36,16 @@ using std::cout;
 using boost::shared_ptr;
 using dcp::Size;
 
-ImageDecoder::ImageDecoder (shared_ptr<const ImageContent> c)
-       : _image_content (c)
+ImageDecoder::ImageDecoder (shared_ptr<const Film> film, shared_ptr<const ImageContent> c)
+       : Decoder (film)
+       , _image_content (c)
        , _frame_video_position (0)
 {
        video.reset (new VideoDecoder (this, c));
 }
 
 bool
-ImageDecoder::pass (boost::shared_ptr<const Film> film)
+ImageDecoder::pass ()
 {
        if (_frame_video_position >= _image_content->video->length()) {
                return true;
@@ -71,14 +72,15 @@ ImageDecoder::pass (boost::shared_ptr<const Film> film)
                }
        }
 
-       video->emit (film, _image, _frame_video_position);
+       video->emit (film(), _image, _frame_video_position);
        ++_frame_video_position;
        return false;
 }
 
 void
-ImageDecoder::seek (shared_ptr<const Film> film, ContentTime time, bool accurate)
+ImageDecoder::seek (ContentTime time, bool accurate)
 {
-       Decoder::seek (film, time, accurate);
-       _frame_video_position = time.frames_round (_image_content->active_video_frame_rate(film));
+       Decoder::seek (
+               time, accurate);
+       _frame_video_position = time.frames_round (_image_content->active_video_frame_rate(film()));
 }
index 25ad9f0..9f1484e 100644 (file)
@@ -27,14 +27,14 @@ class ImageProxy;
 class ImageDecoder : public Decoder
 {
 public:
-       ImageDecoder (boost::shared_ptr<const ImageContent> c);
+       ImageDecoder (boost::shared_ptr<const Film> film, boost::shared_ptr<const ImageContent> c);
 
        boost::shared_ptr<const ImageContent> content () {
                return _image_content;
        }
 
-       bool pass (boost::shared_ptr<const Film> film);
-       void seek (boost::shared_ptr<const Film> film, ContentTime, bool);
+       bool pass ();
+       void seek (ContentTime, bool);
 
 private:
 
index 283a641..80b9744 100644 (file)
@@ -480,7 +480,7 @@ Player::get_reel_assets ()
 
                scoped_ptr<DCPDecoder> decoder;
                try {
-                       decoder.reset (new DCPDecoder (j, false));
+                       decoder.reset (new DCPDecoder (_film, j, false));
                } catch (...) {
                        return a;
                }
@@ -570,7 +570,7 @@ Player::pass ()
                        continue;
                }
 
-               DCPTime const t = content_time_to_dcp (i, max(i->decoder->position(_film), i->content->trim_start()));
+               DCPTime const t = content_time_to_dcp (i, max(i->decoder->position(), i->content->trim_start()));
                if (t > i->content->end(_film)) {
                        i->done = true;
                } else {
@@ -610,7 +610,7 @@ Player::pass ()
 
        switch (which) {
        case CONTENT:
-               earliest_content->done = earliest_content->decoder->pass (_film);
+               earliest_content->done = earliest_content->decoder->pass ();
                break;
        case BLACK:
                emit_video (black_player_video_frame(EYES_BOTH), _black.position());
@@ -1024,11 +1024,11 @@ Player::seek (DCPTime time, bool accurate)
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
                if (time < i->content->position()) {
                        /* Before; seek to the start of the content */
-                       i->decoder->seek (_film, dcp_to_content_time (i, i->content->position()), accurate);
+                       i->decoder->seek (dcp_to_content_time (i, i->content->position()), accurate);
                        i->done = false;
                } else if (i->content->position() <= time && time < i->content->end(_film)) {
                        /* During; seek to position */
-                       i->decoder->seek (_film, dcp_to_content_time (i, time), accurate);
+                       i->decoder->seek (dcp_to_content_time (i, time), accurate);
                        i->done = false;
                } else {
                        /* After; this piece is done */
index e67450b..8c9880b 100644 (file)
@@ -35,8 +35,9 @@ using boost::shared_ptr;
 using boost::optional;
 using boost::dynamic_pointer_cast;
 
-StringTextFileDecoder::StringTextFileDecoder (shared_ptr<const StringTextFileContent> content)
-       : StringTextFile (content)
+StringTextFileDecoder::StringTextFileDecoder (shared_ptr<const Film> film, shared_ptr<const StringTextFileContent> content)
+       : Decoder (film)
+       , StringTextFile (content)
        , _next (0)
 {
        ContentTime first;
@@ -47,7 +48,7 @@ StringTextFileDecoder::StringTextFileDecoder (shared_ptr<const StringTextFileCon
 }
 
 void
-StringTextFileDecoder::seek (shared_ptr<const Film> film, ContentTime time, bool accurate)
+StringTextFileDecoder::seek (ContentTime time, bool accurate)
 {
        /* It's worth back-tracking a little here as decoding is cheap and it's nice if we don't miss
           too many subtitles when seeking.
@@ -57,7 +58,7 @@ StringTextFileDecoder::seek (shared_ptr<const Film> film, ContentTime time, bool
                time = ContentTime();
        }
 
-       Decoder::seek (film, time, accurate);
+       Decoder::seek (time, accurate);
 
        _next = 0;
        while (_next < _subtitles.size() && ContentTime::from_seconds (_subtitles[_next].from.all_as_seconds ()) < time) {
@@ -66,7 +67,7 @@ StringTextFileDecoder::seek (shared_ptr<const Film> film, ContentTime time, bool
 }
 
 bool
-StringTextFileDecoder::pass (shared_ptr<const Film>)
+StringTextFileDecoder::pass ()
 {
        if (_next >= _subtitles.size ()) {
                return true;
index 8cdf8cd..f30e1b7 100644 (file)
@@ -29,10 +29,10 @@ class StringTextFileContent;
 class StringTextFileDecoder : public Decoder, public StringTextFile
 {
 public:
-       StringTextFileDecoder (boost::shared_ptr<const StringTextFileContent>);
+       StringTextFileDecoder (boost::shared_ptr<const Film> film, boost::shared_ptr<const StringTextFileContent>);
 
-       void seek (boost::shared_ptr<const Film> film, ContentTime time, bool accurate);
-       bool pass (boost::shared_ptr<const Film> film);
+       void seek (ContentTime time, bool accurate);
+       bool pass ();
 
 private:
        ContentTimePeriod content_time_period (sub::Subtitle s) const;
index 7d9656d..3c4002c 100644 (file)
@@ -31,8 +31,9 @@
 using boost::shared_ptr;
 using boost::optional;
 
-VideoMXFDecoder::VideoMXFDecoder (shared_ptr<const VideoMXFContent> content)
-       : _content (content)
+VideoMXFDecoder::VideoMXFDecoder (shared_ptr<const Film> film, shared_ptr<const VideoMXFContent> content)
+       : Decoder (film)
+       , _content (content)
 {
        video.reset (new VideoDecoder (this, content));
 
@@ -68,18 +69,19 @@ VideoMXFDecoder::VideoMXFDecoder (shared_ptr<const VideoMXFContent> content)
 }
 
 bool
-VideoMXFDecoder::pass (shared_ptr<const Film> film)
+VideoMXFDecoder::pass ()
 {
-       double const vfr = _content->active_video_frame_rate (film);
+       double const vfr = _content->active_video_frame_rate (film());
        int64_t const frame = _next.frames_round (vfr);
 
+
        if (frame >= _content->video->length()) {
                return true;
        }
 
        if (_mono_reader) {
                video->emit (
-                       film,
+                       film(),
                        shared_ptr<ImageProxy> (
                                new J2KImageProxy (_mono_reader->get_frame(frame), _size, AV_PIX_FMT_XYZ12LE, optional<int>())
                                ),
@@ -87,14 +89,14 @@ VideoMXFDecoder::pass (shared_ptr<const Film> film)
                        );
        } else {
                video->emit (
-                       film,
+                       film(),
                        shared_ptr<ImageProxy> (
                                new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_LEFT, AV_PIX_FMT_XYZ12LE, optional<int>())
                                ),
                        frame
                        );
                video->emit (
-                       film,
+                       film(),
                        shared_ptr<ImageProxy> (
                                new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_RIGHT, AV_PIX_FMT_XYZ12LE, optional<int>())
                                ),
@@ -107,8 +109,8 @@ VideoMXFDecoder::pass (shared_ptr<const Film> film)
 }
 
 void
-VideoMXFDecoder::seek (shared_ptr<const Film> film, ContentTime t, bool accurate)
+VideoMXFDecoder::seek (ContentTime t, bool accurate)
 {
-       Decoder::seek (film, t, accurate);
+       Decoder::seek (t, accurate);
        _next = t;
 }
index 6b5b328..3e3760d 100644 (file)
@@ -28,10 +28,10 @@ class Log;
 class VideoMXFDecoder : public Decoder
 {
 public:
-       VideoMXFDecoder (boost::shared_ptr<const VideoMXFContent>);
+       VideoMXFDecoder (boost::shared_ptr<const Film> film, boost::shared_ptr<const VideoMXFContent>);
 
-       bool pass (boost::shared_ptr<const Film> film);
-       void seek (boost::shared_ptr<const Film> film, ContentTime t, bool accurate);
+       bool pass ();
+       void seek (ContentTime t, bool accurate);
 
 private:
 
index 49a98dc..9b591b1 100644 (file)
@@ -96,7 +96,7 @@ TextView::TextView (
                        i->Stop.connect (bind (&TextView::data_stop, this, _1));
                }
        }
-       while (!decoder->pass (film)) {}
+       while (!decoder->pass ()) {}
        SetSizerAndFit (sizer);
 }
 
index 5a1cf43..89eb11a 100644 (file)
@@ -90,11 +90,11 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_within_dcp_test)
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       shared_ptr<DCPDecoder> decoder (new DCPDecoder (content, false));
+       shared_ptr<DCPDecoder> decoder (new DCPDecoder (film, content, false));
        decoder->only_text()->PlainStart.connect (bind (store, _1));
 
        stored = optional<ContentStringText> ();
-       while (!decoder->pass(film) && !stored) {}
+       while (!decoder->pass() && !stored) {}
 
        BOOST_REQUIRE (stored);
        BOOST_REQUIRE_EQUAL (stored->subs.size(), 2);
@@ -113,11 +113,11 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test2)
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder(content));
+       shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder(film, content));
        decoder->only_text()->PlainStart.connect (bind (store, _1));
 
        stored = optional<ContentStringText> ();
-       while (!decoder->pass(film)) {
+       while (!decoder->pass()) {
                if (stored && stored->from() == ContentTime(0)) {
                        BOOST_CHECK_EQUAL (stored->subs.front().text(), "&lt;b&gt;Hello world!&lt;/b&gt;");
                }
@@ -139,9 +139,9 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test3)
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder (content));
+       shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder (film, content));
        stored = optional<ContentStringText> ();
-       while (!decoder->pass (film)) {
+       while (!decoder->pass ()) {
                decoder->only_text()->PlainStart.connect (bind (store, _1));
                if (stored && stored->from() == ContentTime::from_seconds(0.08)) {
                        list<dcp::SubtitleString> s = stored->subs;
index c6fae48..b8bfe35 100644 (file)
@@ -54,12 +54,12 @@ store (ContentVideo v)
 }
 
 static void
-check (shared_ptr<const Film> film, shared_ptr<FFmpegDecoder> decoder, int frame)
+check (shared_ptr<FFmpegDecoder> decoder, int frame)
 {
        BOOST_REQUIRE (decoder->ffmpeg_content()->video_frame_rate ());
-       decoder->seek (film, ContentTime::from_frames (frame, decoder->ffmpeg_content()->video_frame_rate().get()), true);
+       decoder->seek (ContentTime::from_frames (frame, decoder->ffmpeg_content()->video_frame_rate().get()), true);
        stored = optional<ContentVideo> ();
-       while (!decoder->pass(film) && !stored) {}
+       while (!decoder->pass() && !stored) {}
        BOOST_CHECK (stored->frame <= frame);
 }
 
@@ -77,7 +77,7 @@ test (boost::filesystem::path file, vector<int> frames)
        decoder->video->Data.connect (bind (&store, _1));
 
        for (vector<int>::const_iterator i = frames.begin(); i != frames.end(); ++i) {
-               check (film, decoder, *i);
+               check (decoder, *i);
        }
 }