diff options
| author | Carl Hetherington <cth@carlh.net> | 2020-06-25 09:55:19 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2020-12-01 16:43:36 +0100 |
| commit | 024b0f74e66f718b605ad3a1e4994e7547ffb4ef (patch) | |
| tree | 8741a82e1393c4612523d209fde52a588d8f94cb | |
| parent | fba5241b24e0b7ba7d428bbc1d34edbc239d6c58 (diff) | |
wip: allow multi-content pieces.1771-resample-glitches-take3
| -rw-r--r-- | src/lib/piece.cc | 97 | ||||
| -rw-r--r-- | src/lib/piece.h | 23 | ||||
| -rw-r--r-- | src/lib/player.cc | 142 | ||||
| -rw-r--r-- | src/lib/player.h | 3 |
4 files changed, 187 insertions, 78 deletions
diff --git a/src/lib/piece.cc b/src/lib/piece.cc index 03a92be6c..55ee7d151 100644 --- a/src/lib/piece.cc +++ b/src/lib/piece.cc @@ -19,15 +19,22 @@ */ +#include "atmos_decoder.h" #include "audio_content.h" +#include "audio_decoder.h" #include "audio_stream.h" #include "content.h" #include "dcp_content.h" +#include "dcp_decoder.h" #include "decoder.h" +#include "decoder_factory.h" #include "piece.h" #include "text_content.h" +#include "text_decoder.h" #include "video_content.h" +#include "video_decoder.h" #include <boost/foreach.hpp> +#include <boost/ref.hpp> using std::copy; @@ -36,9 +43,99 @@ using std::map; using boost::dynamic_pointer_cast; using boost::optional; using boost::shared_ptr; +using boost::weak_ptr; using namespace dcpomatic; +Piece::Piece ( + shared_ptr<const Film> film, + ContentList content, + bool fast, + bool tolerant, + bool ignore_video, + bool ignore_audio, + bool ignore_text, + bool play_referenced, + optional<int> dcp_decode_reduction + ) + : _content (content) + , _done (false) +{ + DCPOMATIC_ASSERT (!content.empty()); + + /* We assume here that the contents of the list have the required things the same: + * - video and audio frame rates + * - audio streams and channel counts + */ + + _frc = FrameRateChange (film, _content.front()); + + BOOST_FOREACH (shared_ptr<Content> i, _content) + { + shared_ptr<Decoder> decoder = decoder_factory (film, i, fast, tolerant, shared_ptr<Decoder>()); + DCPOMATIC_ASSERT (decoder); + + if (decoder->video && ignore_video) { + decoder->video->set_ignore (true); + } + + if (decoder->audio && ignore_audio) { + decoder->audio->set_ignore (true); + } + + if (ignore_text) { + BOOST_FOREACH (shared_ptr<TextDecoder> k, decoder->text) { + k->set_ignore (true); + } + } + + shared_ptr<DCPDecoder> dcp = dynamic_pointer_cast<DCPDecoder> (decoder); + if (dcp) { + dcp->set_decode_referenced (play_referenced); + if (play_referenced) { + dcp->set_forced_reduction (dcp_decode_reduction); + } + } + + if (decoder->video) { + if (i->video->frame_type() == VIDEO_FRAME_TYPE_3D_LEFT || i->video->frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) { + /* We need a Shuffler to cope with 3D L/R video data arriving out of sequence */ + /* XXX: move this */ + //decoder->video->Data.connect (bind(&Shuffler::video, _shuffler, weak_ptr<Piece>(piece), _1)); + } else { + decoder->video->Data.connect (bind(boost::ref(Video), _1)); + } + } + + if (decoder->audio) { + decoder->audio->Data.connect (bind(boost::ref(Audio), _1, _2)); + } + + list<shared_ptr<TextDecoder> >::const_iterator k = decoder->text.begin(); + + while (k != decoder->text.end()) { + (*k)->BitmapStart.connect ( + bind(boost::ref(BitmapTextStart), weak_ptr<const TextContent>((*k)->content()), _1) + ); + (*k)->PlainStart.connect ( + bind(boost::ref(PlainTextStart), weak_ptr<const TextContent>((*k)->content()), _1) + ); + (*k)->Stop.connect ( + bind(boost::ref(TextStop), weak_ptr<const TextContent>((*k)->content()), _1) + ); + + ++k; + } + + if (decoder->atmos) { + decoder->atmos->Data.connect (bind(boost::ref(Atmos), _1)); + } + + _decoder.push_back (decoder); + } +} + + Piece::Piece (shared_ptr<Content> c, shared_ptr<Decoder> d, FrameRateChange f) : _frc (f) , _done (false) diff --git a/src/lib/piece.h b/src/lib/piece.h index c07fca20e..60adb23e7 100644 --- a/src/lib/piece.h +++ b/src/lib/piece.h @@ -24,6 +24,10 @@ #include "audio_stream.h" #include "colour_conversion.h" +#include "content_atmos.h" +#include "content_audio.h" +#include "content_text.h" +#include "content_video.h" #include "font.h" #include "dcpomatic_time.h" #include "frame_rate_change.h" @@ -38,6 +42,18 @@ struct check_reuse_old_data_test; class Piece { public: + Piece ( + boost::shared_ptr<const Film> film, + ContentList content, + bool fast, + bool tolerant, + bool ignore_video, + bool ignore_audio, + bool ignore_text, + bool play_referenced, + boost::optional<int> dcp_decode_reduction + ); + Piece (boost::shared_ptr<Content> c, boost::shared_ptr<Decoder> d, FrameRateChange f); void update_pull_to (dcpomatic::DCPTime& pull_to) const; @@ -73,6 +89,13 @@ public: void add_fonts (std::list<boost::shared_ptr<dcpomatic::Font> >& fonts) const; + boost::signals2::signal<void (ContentVideo)> Video; + boost::signals2::signal<void (AudioStreamPtr, ContentAudio)> Audio; + boost::signals2::signal<void (boost::weak_ptr<const TextContent>, ContentBitmapText)> BitmapTextStart; + boost::signals2::signal<void (boost::weak_ptr<const TextContent>, ContentStringText)> PlainTextStart; + boost::signals2::signal<void (boost::weak_ptr<const TextContent>, dcpomatic::ContentTime)> TextStop; + boost::signals2::signal<void (ContentAtmos)> Atmos; + private: friend struct ::check_reuse_old_data_test; diff --git a/src/lib/player.cc b/src/lib/player.cc index 7e96144bb..f076678f0 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -177,91 +177,65 @@ Player::setup_pieces_unlocked () _shuffler = new Shuffler(); _shuffler->Video.connect(bind(&Player::video, this, _1, _2)); - BOOST_FOREACH (shared_ptr<Content> i, playlist()->content()) { - - if (!i->paths_valid ()) { - continue; - } - - if (_ignore_video && _ignore_audio && i->text.empty()) { - /* We're only interested in text and this content has none */ - continue; - } - - shared_ptr<Decoder> old_decoder; - /* XXX: needs to check vector of Content and use the old decoders, but - * this will all be different as we have to coalesce content before - * this happens. - BOOST_FOREACH (shared_ptr<Piece> j, old_pieces) { - if (j->content == i) { - old_decoder = j->decoder; - break; - } - } - */ + BOOST_FOREACH (ContentList const& i, coalesce(playlist()->content())) { - shared_ptr<Decoder> decoder = decoder_factory (_film, i, _fast, _tolerant, old_decoder); - DCPOMATIC_ASSERT (decoder); - - FrameRateChange frc (_film, i); - - if (decoder->video && _ignore_video) { - decoder->video->set_ignore (true); - } - - if (decoder->audio && _ignore_audio) { - decoder->audio->set_ignore (true); - } - - if (_ignore_text) { - BOOST_FOREACH (shared_ptr<TextDecoder> i, decoder->text) { - i->set_ignore (true); - } - } - - shared_ptr<DCPDecoder> dcp = dynamic_pointer_cast<DCPDecoder> (decoder); - if (dcp) { - dcp->set_decode_referenced (_play_referenced); - if (_play_referenced) { - dcp->set_forced_reduction (_dcp_decode_reduction); + bool invalid = false; + bool interesting = true; + BOOST_FOREACH (shared_ptr<Content> j, i) { + if (!j->paths_valid()) { + invalid = true; + continue; } - } - - shared_ptr<Piece> piece (new Piece (i, decoder, frc)); - _pieces.push_back (piece); - - if (decoder->video) { - if (i->video->frame_type() == VIDEO_FRAME_TYPE_3D_LEFT || i->video->frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) { - /* We need a Shuffler to cope with 3D L/R video data arriving out of sequence */ - decoder->video->Data.connect (bind (&Shuffler::video, _shuffler, weak_ptr<Piece>(piece), _1)); - } else { - decoder->video->Data.connect (bind (&Player::video, this, weak_ptr<Piece>(piece), _1)); + if (_ignore_video && _ignore_audio && j->text.empty()) { + /* We're only interested in text and this content has none */ + interesting = false; + continue; } } - if (decoder->audio) { - decoder->audio->Data.connect (bind (&Player::audio, this, weak_ptr<Piece> (piece), _1, _2)); + if (invalid || !interesting) { + continue; } - list<shared_ptr<TextDecoder> >::const_iterator j = decoder->text.begin(); - - while (j != decoder->text.end()) { - (*j)->BitmapStart.connect ( - bind(&Player::bitmap_text_start, this, weak_ptr<Piece>(piece), weak_ptr<const TextContent>((*j)->content()), _1) - ); - (*j)->PlainStart.connect ( - bind(&Player::plain_text_start, this, weak_ptr<Piece>(piece), weak_ptr<const TextContent>((*j)->content()), _1) - ); - (*j)->Stop.connect ( - bind(&Player::subtitle_stop, this, weak_ptr<Piece>(piece), weak_ptr<const TextContent>((*j)->content()), _1) - ); + shared_ptr<Piece> piece( + new Piece( + _film, + i, + _fast, + _tolerant, + _ignore_video, + _ignore_audio, + _ignore_text, + _play_referenced, + _dcp_decode_reduction + )); + + piece->Video.connect (bind(&Player::video, this, weak_ptr<Piece>(piece), _1)); + piece->Audio.connect (bind(&Player::audio, this, weak_ptr<Piece>(piece), _1, _2)); + piece->BitmapTextStart.connect (bind(&Player::bitmap_text_start, this, weak_ptr<Piece>(piece), _1, _2)); + piece->PlainTextStart.connect (bind(&Player::plain_text_start, this, weak_ptr<Piece>(piece), _1, _2)); + piece->TextStop.connect (bind(&Player::text_stop, this, weak_ptr<Piece>(piece), _1, _2)); + piece->Atmos.connect (bind(&Player::atmos, this, weak_ptr<Piece>(piece), _1)); - ++j; - } + _pieces.push_back (piece); - if (decoder->atmos) { - decoder->atmos->Data.connect (bind(&Player::atmos, this, weak_ptr<Piece>(piece), _1)); - } + /* XXX: needs to check vector of Content and use the old decoders, but + * this will all be different as we have to coalesce content before + * this happens. + BOOST_FOREACH (shared_ptr<Piece> j, old_pieces) { + if (j->content == i) { + old_decoder = j->decoder; + break; + } + } + */ + +#if 0 + XXX + if (j->video->frame_type() == VIDEO_FRAME_TYPE_3D_LEFT || j->video->frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) { + /* We need a Shuffler to cope with 3D L/R video data arriving out of sequence */ + decoder->video->Data.connect (bind(&Shuffler::video, _shuffler, weak_ptr<Piece>(piece), _1)); +#endif } _black = Empty (_film, playlist(), bind(&have_video, _1), _playback_length); @@ -988,7 +962,7 @@ Player::plain_text_start (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, Co } void -Player::subtitle_stop (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, ContentTime to) +Player::text_stop (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, ContentTime to) { shared_ptr<const TextContent> text = wc.lock (); if (!text) { @@ -1209,3 +1183,17 @@ Player::atmos (weak_ptr<Piece>, ContentAtmos data) Atmos (data.data, DCPTime::from_frames(data.frame, _film->video_frame_rate()), data.metadata); } + +vector<ContentList> +Player::coalesce (ContentList const& content) const +{ + vector<ContentList> coalesced; + BOOST_FOREACH (shared_ptr<Content> i, content) { + ContentList group; + group.push_back (i); + coalesced.push_back (group); + } + + return coalesced; +} + diff --git a/src/lib/player.h b/src/lib/player.h index eb1b4ea36..2ae1628c3 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -122,6 +122,7 @@ private: void construct (); void setup_pieces (); void setup_pieces_unlocked (); + std::vector<ContentList> coalesce (ContentList const& content) const; void flush (); void film_change (ChangeType, Film::Property); void playlist_change (ChangeType); @@ -132,7 +133,7 @@ private: void audio (boost::weak_ptr<Piece>, AudioStreamPtr, ContentAudio); void bitmap_text_start (boost::weak_ptr<Piece>, boost::weak_ptr<const TextContent>, ContentBitmapText); void plain_text_start (boost::weak_ptr<Piece>, boost::weak_ptr<const TextContent>, ContentStringText); - void subtitle_stop (boost::weak_ptr<Piece>, boost::weak_ptr<const TextContent>, dcpomatic::ContentTime); + void text_stop (boost::weak_ptr<Piece>, boost::weak_ptr<const TextContent>, dcpomatic::ContentTime); void atmos (boost::weak_ptr<Piece>, ContentAtmos); dcpomatic::DCPTime one_video_frame () const; |
