Fix error when padding is needed in 3D encodes (#2476).
[dcpomatic.git] / src / lib / player.cc
index 510def583279819e6e4c60239dec3f7481325399..abcefcab5c57fcae7afbc5db48589cd12088d343 100644 (file)
@@ -378,13 +378,29 @@ Player::setup_pieces ()
                return v && v->use() && v->frame_type() != VideoFrameType::THREE_D_LEFT && v->frame_type() != VideoFrameType::THREE_D_RIGHT;
        };
 
-       for (auto i = _pieces.begin(); i != _pieces.end(); ++i) {
-               if (ignore_overlap((*i)->content->video)) {
+       for (auto piece = _pieces.begin(); piece != _pieces.end(); ++piece) {
+               if (ignore_overlap((*piece)->content->video)) {
                        /* Look for content later in the content list with in-use video that overlaps this */
-                       auto const period = DCPTimePeriod((*i)->content->position(), (*i)->content->end(film));
-                       for (auto j = std::next(i); j != _pieces.end(); ++j) {
-                               if ((*j)->content->video && ignore_overlap((*j)->content->video)) {
-                                       (*i)->ignore_video = DCPTimePeriod((*j)->content->position(), (*j)->content->end(film)).overlap(period);
+                       auto const period = (*piece)->content->period(film);
+                       for (auto later_piece = std::next(piece); later_piece != _pieces.end(); ++later_piece) {
+                               if (ignore_overlap((*later_piece)->content->video)) {
+                                       if (auto overlap = (*later_piece)->content->period(film).overlap(period)) {
+                                               (*piece)->ignore_video.push_back(*overlap);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       for (auto piece = _pieces.begin(); piece != _pieces.end(); ++piece) {
+               if ((*piece)->content->atmos) {
+                       /* Look for content later in the content list with ATMOS that overlaps this */
+                       auto const period = (*piece)->content->period(film);
+                       for (auto later_piece = std::next(piece); later_piece != _pieces.end(); ++later_piece) {
+                               if ((*later_piece)->content->atmos) {
+                                       if (auto overlap = (*later_piece)->content->period(film).overlap(period)) {
+                                               (*piece)->ignore_atmos.push_back(*overlap);
+                                       }
                                }
                        }
                }
@@ -754,7 +770,12 @@ Player::pass ()
        }
        case BLACK:
                LOG_DEBUG_PLAYER ("Emit black for gap at %1", to_string(_black.position()));
-               emit_video (black_player_video_frame(Eyes::BOTH), _black.position());
+               if (film->three_d()) {
+                       emit_video(black_player_video_frame(Eyes::LEFT), _black.position());
+                       emit_video(black_player_video_frame(Eyes::RIGHT), _black.position());
+               } else {
+                       emit_video(black_player_video_frame(Eyes::BOTH), _black.position());
+               }
                _black.set_position (_black.position() + one_video_frame());
                break;
        case SILENT:
@@ -1004,7 +1025,12 @@ Player::video (weak_ptr<Piece> weak_piece, ContentVideo video)
                return;
        }
 
-       if (piece->ignore_video && piece->ignore_video->contains(time)) {
+       auto ignore_video = std::find_if(
+               piece->ignore_video.begin(),
+               piece->ignore_video.end(),
+               [time](DCPTimePeriod period) { return period.contains(time); }
+               );
+       if (ignore_video != piece->ignore_video.end()) {
                return;
        }
 
@@ -1592,6 +1618,15 @@ Player::atmos (weak_ptr<Piece> weak_piece, ContentAtmos data)
                return;
        }
 
+       auto ignore_atmos = std::find_if(
+               piece->ignore_atmos.begin(),
+               piece->ignore_atmos.end(),
+               [dcp_time](DCPTimePeriod period) { return period.contains(dcp_time); }
+               );
+       if (ignore_atmos != piece->ignore_atmos.end()) {
+               return;
+       }
+
        Atmos (data.data, dcp_time, data.metadata);
 }