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 0bd28a9e37de0d1ce51d5e4a7bdb7e9fc86fba1e..62284e4333e06a1ceb62bfaebc99fd83a41a7ab4 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 a67b244f75392b4803a7d1638372c80e216f1070..1098bb87a8c94a8df56cf2ca0f3a7d40cd24f72c 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 d3c5c57eddc368ba65f68c77b37713bf1f52fffb..4068696eafe397620b824d3665a0f0e9e541752d 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 07e879ddfad8ac0d685980bba67c95cc29783643..6c95b8b1fa4aadcc99396e51d3e09102d7739104 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 7e832241e82fa211e2572091c6ca2ef52fd9e1f2..e5533927b4b77f9e485ff56efcd498f8f0dc8976 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 fb7663f5ca8833caadcd02cd46034b8733f07491..52e8c04e6984f26d389d74ec61189fa80f749a69 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 a8a67ee72624224afdb4af65db9d4522a7a6f23a..d610f8727c902cd6bf889ab8cbc024ba3981f606 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 b3e16a3f01a48c28284464246fea66da817559ff..4b2a594e1e3c365f9b5c692cf7897d594e7994cc 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 0e40f128b4e48886ea1f6f66dee0139f4b757115..fbc0ee416b77dcb74db59aba773265a0fddab750 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 408ce30a7b731b94fa5e07bf4f53056491a8b2c7..640229f23f74a757e39df7368bcec0ccec9ac0a8 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 ce8843b0d76b9c45c08d239ac1d6be4024e5bc5c..a9e473f25e52e500d807d59a4a662552c28c4a7c 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 25ad9f07f6de365eed3d3796e41e47c96d2d0145..9f1484e47a33c8fe83a9a1b004592f5dd7057ab8 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 283a641d9ac178fabd890f23e710e00b4d878614..80b9744d8505a884c60d5cc8712ecce90b05cabb 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 e67450b8b719efe38527d74f5b908de3c67a9290..8c9880b0c7118881942b3cebb2ab76991e25bf06 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 8cdf8cd9eb4eeff770630d203ff91614c88129a9..f30e1b7625dee96a1fc7d569c8f64f91c3168124 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 7d9656dd5a7d755aabf1379c42212cb33c1f2326..3c4002ca2b6d9acbbe20079627ebd5f3f39f0c94 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 6b5b328ac09aebe0956ec705b8bd5ba046df5fde..3e3760d97f7e75963e5df014b55ee79d7cbd4d38 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 49a98dc5e3c06f4647aa742093c50f6a5061a613..9b591b19161406408c88bef739a4c4323a1f91d0 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 5a1cf4391123eacee35b2db6e0e3b3cbeeb155c4..89eb11a6056b724ed4b232d4c643f30c8b1b03bc 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 c6fae48cda4b2a1f9c33dbd2515f3adcae4efff5..b8bfe3532d144d6f54df28f3e705a7b8d9c57783 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);
        }
 }