- while (
- !_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.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<int>(_store.front().second.eyes));
+ string const last = _last ? String::compose("last frame=%1 eyes=%2", _last->frame, static_cast<int>(_last->eyes)) : "no last";
+ LOG_DEBUG_THREED("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);
+ }