summaryrefslogtreecommitdiff
path: root/src/lib/shuffler.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-07-03 15:38:52 +0200
committerCarl Hetherington <cth@carlh.net>2025-07-03 15:38:52 +0200
commit1fa1a2d5e33d9f9c7ad3762940516248664ac773 (patch)
tree7d9ed0bcea2d4fbc7331a1af2757f369de0fa60e /src/lib/shuffler.cc
parentc4f7b352e6d4b774e2305011e3351404f53875b1 (diff)
Insert black for missing 3D eyes in the Shuffler (#3056).3056-3d-crash
Diffstat (limited to 'src/lib/shuffler.cc')
-rw-r--r--src/lib/shuffler.cc31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/lib/shuffler.cc b/src/lib/shuffler.cc
index 57c17ad46..56987a3cf 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>
@@ -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));
+ /* 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());
Video(_store.front().first, _store.front().second);
_last = _store.front().second;
+
+ if (extra && *extra == Eyes::RIGHT) {
+ emit_black(*extra);
+ }
+
_store.pop_front();
}
}