diff options
Diffstat (limited to 'src/lib/shuffler.cc')
| -rw-r--r-- | src/lib/shuffler.cc | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/src/lib/shuffler.cc b/src/lib/shuffler.cc index 57c17ad46..aa3be6506 100644 --- a/src/lib/shuffler.cc +++ b/src/lib/shuffler.cc @@ -22,6 +22,8 @@ #include "content_video.h" #include "dcpomatic_assert.h" #include "dcpomatic_log.h" +#include "image.h" +#include "raw_image_proxy.h" #include "shuffler.h" #include <iostream> #include <string> @@ -40,7 +42,7 @@ int const Shuffler::_max_size = 64; void Shuffler::video(weak_ptr<Piece> weak_piece, ContentVideo video) { - LOG_DEBUG_THREE_D("Shuffler::video time=%1 eyes=%2 part=%3", to_string(video.time), static_cast<int>(video.eyes), static_cast<int>(video.part)); + LOG_DEBUG_THREE_D("Shuffler::video time={} eyes={} part={}", to_string(video.time), static_cast<int>(video.eyes), static_cast<int>(video.part)); if (video.eyes != Eyes::LEFT && video.eyes != Eyes::RIGHT) { /* Pass through anything that we don't care about */ @@ -52,7 +54,7 @@ Shuffler::video(weak_ptr<Piece> weak_piece, ContentVideo video) DCPOMATIC_ASSERT(piece); if (!_last && video.eyes == Eyes::LEFT) { - LOG_DEBUG_THREE_D_NC("Shuffler first after clear"); + LOG_DEBUG_THREE_D("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; @@ -78,9 +80,9 @@ Shuffler::video(weak_ptr<Piece> weak_piece, ContentVideo video) ); if (!store_front_in_sequence) { - string const store = _store.empty() ? "store empty" : String::compose("store front time=%1 eyes=%2", to_string(_store.front().second.time), static_cast<int>(_store.front().second.eyes)); - string const last = _last ? String::compose("last time=%1 eyes=%2", to_string(_last->time), static_cast<int>(_last->eyes)) : "no last"; - LOG_DEBUG_THREE_D("Shuffler not in sequence: %1 %2", store, last); + string const store = _store.empty() ? "store empty" : fmt::format("store front time={} eyes={}", to_string(_store.front().second.time), static_cast<int>(_store.front().second.eyes)); + string const last = _last ? fmt::format("last time={} eyes={}", to_string(_last->time), static_cast<int>(_last->eyes)) : "no last"; + LOG_DEBUG_THREE_D("Shuffler not in sequence: {} {}", store, last); } if (!store_front_in_sequence && _store.size() <= _max_size) { @@ -91,13 +93,42 @@ Shuffler::video(weak_ptr<Piece> weak_piece, ContentVideo video) break; } + optional<Eyes> extra; + if (_store.size() > _max_size) { - LOG_WARNING("Shuffler is full after receiving frame at %1; 3D sync may be incorrect.", to_string(video.time)); + LOG_WARNING("Shuffler is full after receiving frame at {}; 3D sync may be incorrect.", to_string(video.time)); + /* Now that we've given up waiting for the correct frames to arrive, we may need to insert some extra + * left/right eyes so that the player doesn't wait forever for lefts/rights that will never come. + * Set extra to the extra eye that we should insert based on what we'll emit now and what's coming next. + */ + auto const& this_frame = _store.front(); + auto const& next_frame = *std::next(_store.begin()); + if (this_frame.second.eyes == next_frame.second.eyes) { + extra = this_frame.second.eyes == Eyes::LEFT ? Eyes::RIGHT : Eyes::LEFT; + } + } + + auto emit_black = [this](Eyes eyes) { + LOG_DEBUG_THREE_D("Shuffler emits extra time=%1 eyes=%2 store=%3", to_string(_store.front().second.time), static_cast<int>(eyes), _store.size()); + auto image = std::make_shared<Image>(AV_PIX_FMT_RGB24, dcp::Size(64, 64), Image::Alignment::COMPACT); + image->make_black(); + auto proxy = std::make_shared<RawImageProxy>(image); + ContentVideo black(proxy, _store.front().second.time, eyes, _store.front().second.part); + Video(_store.front().first, black); + }; + + if (extra && *extra == Eyes::LEFT) { + emit_black(*extra); } - LOG_DEBUG_THREE_D("Shuffler emits time=%1 eyes=%2 store=%3", to_string(_store.front().second.time), static_cast<int>(_store.front().second.eyes), _store.size()); + LOG_DEBUG_THREE_D("Shuffler emits time={} eyes={} store={}", to_string(_store.front().second.time), static_cast<int>(_store.front().second.eyes), _store.size()); Video(_store.front().first, _store.front().second); _last = _store.front().second; + + if (extra && *extra == Eyes::RIGHT) { + emit_black(*extra); + } + _store.pop_front(); } } @@ -106,7 +137,7 @@ Shuffler::video(weak_ptr<Piece> weak_piece, ContentVideo video) void Shuffler::clear() { - LOG_DEBUG_THREE_D_NC("Shuffler::clear"); + LOG_DEBUG_THREE_D("Shuffler::clear"); _store.clear(); _last = optional<ContentVideo>(); } |
