X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fshuffler.cc;h=5a4faf4d15fa4c0f74617bd2bd03ecd57f1ba114;hb=ccd69987ab861ea4521836fa2a5227e2dfac3479;hp=00edc27d5983c7e88ff1fb3b9790b35dc821a7c4;hpb=5f5c64faa7b0114f84f45e50211611333042c672;p=dcpomatic.git diff --git a/src/lib/shuffler.cc b/src/lib/shuffler.cc index 00edc27d5..5a4faf4d1 100644 --- a/src/lib/shuffler.cc +++ b/src/lib/shuffler.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Carl Hetherington + Copyright (C) 2018-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,17 +18,25 @@ */ + #include "shuffler.h" #include "content_video.h" #include "dcpomatic_assert.h" -#include +#include "dcpomatic_log.h" +#include #include + using std::make_pair; -using boost::weak_ptr; -using boost::shared_ptr; +using std::shared_ptr; +using std::string; +using std::weak_ptr; using boost::optional; + +int const Shuffler::_max_size = 64; + + struct Comparator { bool operator()(Shuffler::Store const & a, Shuffler::Store const & b) { @@ -39,16 +47,23 @@ struct Comparator } }; + void Shuffler::video (weak_ptr weak_piece, ContentVideo video) { - /* We should only ever see 3D_LEFT / 3D_RIGHT */ - DCPOMATIC_ASSERT (video.eyes == EYES_LEFT || video.eyes == EYES_RIGHT); + LOG_DEBUG_THREE_D ("Shuffler::video frame=%1 eyes=%2 part=%3", video.frame, static_cast(video.eyes), static_cast(video.part)); + + if (video.eyes != Eyes::LEFT && video.eyes != Eyes::RIGHT) { + /* Pass through anything that we don't care about */ + Video (weak_piece, video); + return; + } - shared_ptr piece = weak_piece.lock (); + auto piece = weak_piece.lock (); DCPOMATIC_ASSERT (piece); - if (!_last && video.eyes == EYES_LEFT) { + if (!_last && video.eyes == Eyes::LEFT) { + LOG_DEBUG_THREE_D_NC ("Shuffler first after clear"); /* We haven't seen anything since the last clear() and we have some eyes-left so assume everything is OK */ Video (weak_piece, video); _last = video; @@ -58,36 +73,55 @@ Shuffler::video (weak_ptr weak_piece, ContentVideo video) _store.push_back (make_pair (weak_piece, video)); _store.sort (Comparator()); - bool const store_front_in_sequence = - !_store.empty() && - _last && - ( - (_store.front().second.frame == _last->frame && _store.front().second.eyes == EYES_RIGHT && _last->eyes == EYES_LEFT) || - (_store.front().second.frame == (_last->frame + 1) && _store.front().second.eyes == EYES_LEFT && _last->eyes == EYES_RIGHT) - ); - - /* store_front_in_sequence means everything is ok; otherwise if the store is getting too big just - start emitting things as best we can. This can easily happen if, for example, there is only content - for one eye in some part of the timeline. - */ - while (store_front_in_sequence || _store.size() > 8) { + while (true) { + + bool const store_front_in_sequence = + !_store.empty() && + _last && + ( + (_store.front().second.frame == _last->frame && _store.front().second.eyes == Eyes::RIGHT && _last->eyes == Eyes::LEFT) || + (_store.front().second.frame >= (_last->frame + 1) && _store.front().second.eyes == Eyes::LEFT && _last->eyes == Eyes::RIGHT) + ); + + if (!store_front_in_sequence) { + string const store = _store.empty() ? "store empty" : String::compose("store front frame=%1 eyes=%2", _store.front().second.frame, static_cast(_store.front().second.eyes)); + string const last = _last ? String::compose("last frame=%1 eyes=%2", _last->frame, static_cast(_last->eyes)) : "no last"; + LOG_DEBUG_THREE_D("Shuffler not in sequence: %1 %2", store, last); + } + + if (!store_front_in_sequence && _store.size() <= _max_size) { + /* store_front_in_sequence means everything is ok; otherwise if the store is getting too big just + start emitting things as best we can. This can easily happen if, for example, there is only content + for one eye in some part of the timeline. + */ + break; + } + + if (_store.size() > _max_size) { + LOG_WARNING ("Shuffler is full after receiving frame %1; 3D sync may be incorrect.", video.frame); + } + + LOG_DEBUG_THREE_D("Shuffler emits frame=%1 eyes=%2 store=%3", _store.front().second.frame, static_cast(_store.front().second.eyes), _store.size()); Video (_store.front().first, _store.front().second); _last = _store.front().second; _store.pop_front (); } } + void Shuffler::clear () { + LOG_DEBUG_THREE_D_NC ("Shuffler::clear"); _store.clear (); _last = optional(); } + void Shuffler::flush () { - BOOST_FOREACH (Store i, _store) { + for (auto i: _store) { Video (i.first, i.second); } }