From 84012cdd64f451891febd36154b7226ea21a899b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 21 Nov 2018 02:45:30 +0000 Subject: [PATCH] Put Film pointer into Decoder. --- src/lib/dcp_content.cc | 5 ++-- src/lib/dcp_decoder.cc | 42 ++++++++++++++--------------- src/lib/dcp_decoder.h | 9 +++---- src/lib/dcp_subtitle_decoder.cc | 9 ++++--- src/lib/dcp_subtitle_decoder.h | 6 ++--- src/lib/decoder.cc | 32 ++++++++++++++++------ src/lib/decoder.h | 15 ++++++++--- src/lib/decoder_factory.cc | 10 +++---- src/lib/ffmpeg_decoder.cc | 41 ++++++++++++++-------------- src/lib/ffmpeg_decoder.h | 10 +++---- src/lib/image_decoder.cc | 16 ++++++----- src/lib/image_decoder.h | 6 ++--- src/lib/player.cc | 10 +++---- src/lib/string_text_file_decoder.cc | 11 ++++---- src/lib/string_text_file_decoder.h | 6 ++--- src/lib/video_mxf_decoder.cc | 20 +++++++------- src/lib/video_mxf_decoder.h | 6 ++--- src/wx/text_view.cc | 2 +- test/dcp_subtitle_test.cc | 12 ++++----- test/ffmpeg_decoder_seek_test.cc | 8 +++--- 20 files changed, 153 insertions(+), 123 deletions(-) diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc index 0bd28a9e3..62284e433 100644 --- a/src/lib/dcp_content.cc +++ b/src/lib/dcp_content.cc @@ -612,7 +612,7 @@ DCPContent::can_reference_audio (shared_ptr film, string& why_not) c { shared_ptr 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 film, TextType type, stri { shared_ptr 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) { diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index a67b244f7..1098bb87a 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -55,8 +55,9 @@ using boost::shared_ptr; using boost::dynamic_pointer_cast; using boost::optional; -DCPDecoder::DCPDecoder (shared_ptr c, bool fast) +DCPDecoder::DCPDecoder (shared_ptr film, shared_ptr c, bool fast) : DCP (c) + , Decoder (film) , _decode_referenced (false) { if (c->video) { @@ -101,13 +102,13 @@ DCPDecoder::DCPDecoder (shared_ptr c, bool fast) bool -DCPDecoder::pass (shared_ptr 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 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 ( new J2KImageProxy ( _mono_reader->get_frame (entry_point + frame), @@ -137,7 +138,7 @@ DCPDecoder::pass (shared_ptr film) ); } else { video->emit ( - film, + film(), shared_ptr ( new J2KImageProxy ( _stereo_reader->get_frame (entry_point + frame), @@ -151,7 +152,7 @@ DCPDecoder::pass (shared_ptr film) ); video->emit ( - film, + film(), shared_ptr ( new J2KImageProxy ( _stereo_reader->get_frame (entry_point + frame), @@ -182,7 +183,7 @@ DCPDecoder::pass (shared_ptr 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 film) } void -DCPDecoder::pass_texts (shared_ptr film, ContentTime next, dcp::Size size) +DCPDecoder::pass_texts (ContentTime next, dcp::Size size) { list >::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 film, ContentTime next, dcp::Size BOOST_FOREACH (shared_ptr 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 film, ContentTime next, dcp::Size void DCPDecoder::pass_texts ( - shared_ptr film, ContentTime next, shared_ptr asset, bool reference, int64_t entry_point, shared_ptr decoder, dcp::Size size + ContentTime next, shared_ptr asset, bool reference, int64_t entry_point, shared_ptr 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 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 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 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 (); } diff --git a/src/lib/dcp_decoder.h b/src/lib/dcp_decoder.h index d3c5c57ed..4068696ea 100644 --- a/src/lib/dcp_decoder.h +++ b/src/lib/dcp_decoder.h @@ -40,7 +40,7 @@ struct dcp_subtitle_within_dcp_test; class DCPDecoder : public DCP, public Decoder { public: - DCPDecoder (boost::shared_ptr, bool fast); + DCPDecoder (boost::shared_ptr film, boost::shared_ptr, bool fast); std::list > reels () const { return _reels; @@ -49,17 +49,16 @@ public: void set_decode_referenced (bool r); void set_forced_reduction (boost::optional reduction); - bool pass (boost::shared_ptr film); - void seek (boost::shared_ptr 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 film, ContentTime next, dcp::Size size); + void pass_texts (ContentTime next, dcp::Size size); void pass_texts ( - boost::shared_ptr film, ContentTime next, boost::shared_ptr asset, bool reference, diff --git a/src/lib/dcp_subtitle_decoder.cc b/src/lib/dcp_subtitle_decoder.cc index 07e879ddf..6c95b8b1f 100644 --- a/src/lib/dcp_subtitle_decoder.cc +++ b/src/lib/dcp_subtitle_decoder.cc @@ -29,7 +29,8 @@ using boost::shared_ptr; using boost::dynamic_pointer_cast; using boost::bind; -DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr content) +DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr film, shared_ptr content) + : Decoder (film) { shared_ptr c (load (content->path (0))); _subtitles = c->subtitles (); @@ -43,9 +44,9 @@ DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr con } void -DCPSubtitleDecoder::seek (shared_ptr film, ContentTime time, bool accurate) +DCPSubtitleDecoder::seek (ContentTime time, bool accurate) { - Decoder::seek (film, time, accurate); + Decoder::seek (time, accurate); _next = _subtitles.begin (); list >::const_iterator i = _subtitles.begin (); @@ -55,7 +56,7 @@ DCPSubtitleDecoder::seek (shared_ptr film, ContentTime time, bool ac } bool -DCPSubtitleDecoder::pass (shared_ptr) +DCPSubtitleDecoder::pass () { if (_next == _subtitles.end ()) { return true; diff --git a/src/lib/dcp_subtitle_decoder.h b/src/lib/dcp_subtitle_decoder.h index 7e832241e..e5533927b 100644 --- a/src/lib/dcp_subtitle_decoder.h +++ b/src/lib/dcp_subtitle_decoder.h @@ -26,10 +26,10 @@ class DCPSubtitleContent; class DCPSubtitleDecoder : public DCPSubtitle, public Decoder { public: - DCPSubtitleDecoder (boost::shared_ptr); + DCPSubtitleDecoder (boost::shared_ptr film, boost::shared_ptr); - bool pass (boost::shared_ptr film); - void seek (boost::shared_ptr film, ContentTime time, bool accurate); + bool pass (); + void seek (ContentTime time, bool accurate); private: ContentTimePeriod content_time_period (boost::shared_ptr s) const; diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index fb7663f5c..52e8c04e6 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -28,24 +28,32 @@ using std::cout; using boost::optional; using boost::shared_ptr; +using boost::weak_ptr; + +Decoder::Decoder (weak_ptr film) + : _film (film) +{ + +} /** @return Earliest time of content that the next pass() will emit */ ContentTime -Decoder::position (shared_ptr film) const +Decoder::position () const { optional pos; + shared_ptr 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 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 film) const } void -Decoder::seek (shared_ptr, ContentTime, bool) +Decoder::seek (ContentTime, bool) { if (video) { video->seek (); @@ -75,3 +83,11 @@ Decoder::only_text () const } return text.front (); } + +shared_ptr +Decoder::film () const +{ + shared_ptr f = _film.lock (); + DCPOMATIC_ASSERT (f); + return f; +} diff --git a/src/lib/decoder.h b/src/lib/decoder.h index a8a67ee72..d610f8727 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -26,6 +26,7 @@ #define DCPOMATIC_DECODER_H #include "types.h" +#include "film.h" #include "dcpomatic_time.h" #include @@ -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 film); virtual ~Decoder () {} boost::shared_ptr 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 film) = 0; - virtual void seek (boost::shared_ptr film, ContentTime time, bool accurate); + virtual bool pass () = 0; + virtual void seek (ContentTime time, bool accurate); - ContentTime position (boost::shared_ptr film) const; + ContentTime position () const; + +protected: + boost::shared_ptr film () const; + +private: + boost::weak_ptr _film; }; #endif diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc index b3e16a3f0..4b2a594e1 100644 --- a/src/lib/decoder_factory.cc +++ b/src/lib/decoder_factory.cc @@ -47,7 +47,7 @@ decoder_factory (shared_ptr film, shared_ptr content, shared_ptr dc = dynamic_pointer_cast (content); if (dc) { try { - return shared_ptr (new DCPDecoder(dc, fast)); + return shared_ptr (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(); @@ -56,22 +56,22 @@ decoder_factory (shared_ptr film, shared_ptr content, shared_ptr ic = dynamic_pointer_cast (content); if (ic) { - return shared_ptr (new ImageDecoder(ic)); + return shared_ptr (new ImageDecoder(film, ic)); } shared_ptr rc = dynamic_pointer_cast (content); if (rc) { - return shared_ptr (new StringTextFileDecoder(rc)); + return shared_ptr (new StringTextFileDecoder(film, rc)); } shared_ptr dsc = dynamic_pointer_cast (content); if (dsc) { - return shared_ptr (new DCPSubtitleDecoder(dsc)); + return shared_ptr (new DCPSubtitleDecoder(film, dsc)); } shared_ptr vmc = dynamic_pointer_cast (content); if (vmc) { - return shared_ptr (new VideoMXFDecoder(vmc)); + return shared_ptr (new VideoMXFDecoder(film, vmc)); } return shared_ptr (); diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 0e40f128b..fbc0ee416 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -80,6 +80,7 @@ using dcp::Size; FFmpegDecoder::FFmpegDecoder (shared_ptr film, shared_ptr c, bool fast) : FFmpeg (c) + , Decoder (film) , _have_current_subtitle (false) { if (c->video) { @@ -105,7 +106,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr film, shared_ptr film) +FFmpegDecoder::flush () { /* Get any remaining frames */ @@ -114,29 +115,29 @@ FFmpegDecoder::flush (shared_ptr 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 (new RawImageProxy (_black_image)), v); + video->emit (film(), shared_ptr (new RawImageProxy (_black_image)), v); ++v; } } BOOST_FOREACH (shared_ptr 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 film) ContentTime to_do = min (full_length - a, ContentTime::from_seconds (0.1)); shared_ptr 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 film) } bool -FFmpegDecoder::pass (shared_ptr film) +FFmpegDecoder::pass () { int r = av_read_frame (_format_context, &_packet); @@ -174,7 +175,7 @@ FFmpegDecoder::pass (shared_ptr 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 film) shared_ptr 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 stream) con } void -FFmpegDecoder::seek (shared_ptr 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 film, ContentTime time, bool accurat } void -FFmpegDecoder::decode_audio_packet (shared_ptr 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 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 film) } bool -FFmpegDecoder::decode_video_packet (shared_ptr film) +FFmpegDecoder::decode_video_packet () { DCPOMATIC_ASSERT (_video_stream); @@ -526,9 +527,9 @@ FFmpegDecoder::decode_video_packet (shared_ptr 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 (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"); diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 408ce30a7..640229f23 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -47,19 +47,19 @@ class FFmpegDecoder : public FFmpeg, public Decoder public: FFmpegDecoder (boost::shared_ptr film, boost::shared_ptr, bool fast); - bool pass (boost::shared_ptr film); - void seek (boost::shared_ptr film, ContentTime time, bool); + bool pass (); + void seek (ContentTime time, bool); private: friend struct ::ffmpeg_pts_offset_test; - void flush (boost::shared_ptr film); + void flush (); AVSampleFormat audio_sample_format (boost::shared_ptr stream) const; int bytes_per_audio_sample (boost::shared_ptr stream) const; - bool decode_video_packet (boost::shared_ptr film); - void decode_audio_packet (boost::shared_ptr film); + bool decode_video_packet (); + void decode_audio_packet (); void decode_subtitle_packet (); void decode_bitmap_subtitle (AVSubtitleRect const * rect, ContentTime from); diff --git a/src/lib/image_decoder.cc b/src/lib/image_decoder.cc index ce8843b0d..a9e473f25 100644 --- a/src/lib/image_decoder.cc +++ b/src/lib/image_decoder.cc @@ -36,15 +36,16 @@ using std::cout; using boost::shared_ptr; using dcp::Size; -ImageDecoder::ImageDecoder (shared_ptr c) - : _image_content (c) +ImageDecoder::ImageDecoder (shared_ptr film, shared_ptr c) + : Decoder (film) + , _image_content (c) , _frame_video_position (0) { video.reset (new VideoDecoder (this, c)); } bool -ImageDecoder::pass (boost::shared_ptr film) +ImageDecoder::pass () { if (_frame_video_position >= _image_content->video->length()) { return true; @@ -71,14 +72,15 @@ ImageDecoder::pass (boost::shared_ptr 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 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())); } diff --git a/src/lib/image_decoder.h b/src/lib/image_decoder.h index 25ad9f07f..9f1484e47 100644 --- a/src/lib/image_decoder.h +++ b/src/lib/image_decoder.h @@ -27,14 +27,14 @@ class ImageProxy; class ImageDecoder : public Decoder { public: - ImageDecoder (boost::shared_ptr c); + ImageDecoder (boost::shared_ptr film, boost::shared_ptr c); boost::shared_ptr content () { return _image_content; } - bool pass (boost::shared_ptr film); - void seek (boost::shared_ptr film, ContentTime, bool); + bool pass (); + void seek (ContentTime, bool); private: diff --git a/src/lib/player.cc b/src/lib/player.cc index 283a641d9..80b9744d8 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -480,7 +480,7 @@ Player::get_reel_assets () scoped_ptr 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 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 */ diff --git a/src/lib/string_text_file_decoder.cc b/src/lib/string_text_file_decoder.cc index e67450b8b..8c9880b0c 100644 --- a/src/lib/string_text_file_decoder.cc +++ b/src/lib/string_text_file_decoder.cc @@ -35,8 +35,9 @@ using boost::shared_ptr; using boost::optional; using boost::dynamic_pointer_cast; -StringTextFileDecoder::StringTextFileDecoder (shared_ptr content) - : StringTextFile (content) +StringTextFileDecoder::StringTextFileDecoder (shared_ptr film, shared_ptr content) + : Decoder (film) + , StringTextFile (content) , _next (0) { ContentTime first; @@ -47,7 +48,7 @@ StringTextFileDecoder::StringTextFileDecoder (shared_ptr 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 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 film, ContentTime time, bool } bool -StringTextFileDecoder::pass (shared_ptr) +StringTextFileDecoder::pass () { if (_next >= _subtitles.size ()) { return true; diff --git a/src/lib/string_text_file_decoder.h b/src/lib/string_text_file_decoder.h index 8cdf8cd9e..f30e1b762 100644 --- a/src/lib/string_text_file_decoder.h +++ b/src/lib/string_text_file_decoder.h @@ -29,10 +29,10 @@ class StringTextFileContent; class StringTextFileDecoder : public Decoder, public StringTextFile { public: - StringTextFileDecoder (boost::shared_ptr); + StringTextFileDecoder (boost::shared_ptr film, boost::shared_ptr); - void seek (boost::shared_ptr film, ContentTime time, bool accurate); - bool pass (boost::shared_ptr film); + void seek (ContentTime time, bool accurate); + bool pass (); private: ContentTimePeriod content_time_period (sub::Subtitle s) const; diff --git a/src/lib/video_mxf_decoder.cc b/src/lib/video_mxf_decoder.cc index 7d9656dd5..3c4002ca2 100644 --- a/src/lib/video_mxf_decoder.cc +++ b/src/lib/video_mxf_decoder.cc @@ -31,8 +31,9 @@ using boost::shared_ptr; using boost::optional; -VideoMXFDecoder::VideoMXFDecoder (shared_ptr content) - : _content (content) +VideoMXFDecoder::VideoMXFDecoder (shared_ptr film, shared_ptr content) + : Decoder (film) + , _content (content) { video.reset (new VideoDecoder (this, content)); @@ -68,18 +69,19 @@ VideoMXFDecoder::VideoMXFDecoder (shared_ptr content) } bool -VideoMXFDecoder::pass (shared_ptr 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 ( new J2KImageProxy (_mono_reader->get_frame(frame), _size, AV_PIX_FMT_XYZ12LE, optional()) ), @@ -87,14 +89,14 @@ VideoMXFDecoder::pass (shared_ptr film) ); } else { video->emit ( - film, + film(), shared_ptr ( new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_LEFT, AV_PIX_FMT_XYZ12LE, optional()) ), frame ); video->emit ( - film, + film(), shared_ptr ( new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_RIGHT, AV_PIX_FMT_XYZ12LE, optional()) ), @@ -107,8 +109,8 @@ VideoMXFDecoder::pass (shared_ptr film) } void -VideoMXFDecoder::seek (shared_ptr film, ContentTime t, bool accurate) +VideoMXFDecoder::seek (ContentTime t, bool accurate) { - Decoder::seek (film, t, accurate); + Decoder::seek (t, accurate); _next = t; } diff --git a/src/lib/video_mxf_decoder.h b/src/lib/video_mxf_decoder.h index 6b5b328ac..3e3760d97 100644 --- a/src/lib/video_mxf_decoder.h +++ b/src/lib/video_mxf_decoder.h @@ -28,10 +28,10 @@ class Log; class VideoMXFDecoder : public Decoder { public: - VideoMXFDecoder (boost::shared_ptr); + VideoMXFDecoder (boost::shared_ptr film, boost::shared_ptr); - bool pass (boost::shared_ptr film); - void seek (boost::shared_ptr film, ContentTime t, bool accurate); + bool pass (); + void seek (ContentTime t, bool accurate); private: diff --git a/src/wx/text_view.cc b/src/wx/text_view.cc index 49a98dc5e..9b591b191 100644 --- a/src/wx/text_view.cc +++ b/src/wx/text_view.cc @@ -96,7 +96,7 @@ TextView::TextView ( i->Stop.connect (bind (&TextView::data_stop, this, _1)); } } - while (!decoder->pass (film)) {} + while (!decoder->pass ()) {} SetSizerAndFit (sizer); } diff --git a/test/dcp_subtitle_test.cc b/test/dcp_subtitle_test.cc index 5a1cf4391..89eb11a60 100644 --- a/test/dcp_subtitle_test.cc +++ b/test/dcp_subtitle_test.cc @@ -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 decoder (new DCPDecoder (content, false)); + shared_ptr decoder (new DCPDecoder (film, content, false)); decoder->only_text()->PlainStart.connect (bind (store, _1)); stored = optional (); - 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 decoder (new DCPSubtitleDecoder(content)); + shared_ptr decoder (new DCPSubtitleDecoder(film, content)); decoder->only_text()->PlainStart.connect (bind (store, _1)); stored = optional (); - while (!decoder->pass(film)) { + while (!decoder->pass()) { if (stored && stored->from() == ContentTime(0)) { BOOST_CHECK_EQUAL (stored->subs.front().text(), "<b>Hello world!</b>"); } @@ -139,9 +139,9 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test3) film->make_dcp (); BOOST_REQUIRE (!wait_for_jobs ()); - shared_ptr decoder (new DCPSubtitleDecoder (content)); + shared_ptr decoder (new DCPSubtitleDecoder (film, content)); stored = optional (); - 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 s = stored->subs; diff --git a/test/ffmpeg_decoder_seek_test.cc b/test/ffmpeg_decoder_seek_test.cc index c6fae48cd..b8bfe3532 100644 --- a/test/ffmpeg_decoder_seek_test.cc +++ b/test/ffmpeg_decoder_seek_test.cc @@ -54,12 +54,12 @@ store (ContentVideo v) } static void -check (shared_ptr film, shared_ptr decoder, int frame) +check (shared_ptr 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 (); - while (!decoder->pass(film) && !stored) {} + while (!decoder->pass() && !stored) {} BOOST_CHECK (stored->frame <= frame); } @@ -77,7 +77,7 @@ test (boost::filesystem::path file, vector frames) decoder->video->Data.connect (bind (&store, _1)); for (vector::const_iterator i = frames.begin(); i != frames.end(); ++i) { - check (film, decoder, *i); + check (decoder, *i); } } -- 2.30.2