Make EmptyVideo work with stereo a little better.
[dcpomatic.git] / src / lib / empty_video.cc
index c578559e017e27f9d1f3145117a664349ac78156..b99f911f2238fe8424fe043416e37d66451f3e6f 100644 (file)
@@ -35,23 +35,54 @@ using std::cout;
 using std::dynamic_pointer_cast;
 using std::function;
 using std::list;
+using std::make_pair;
+using std::pair;
 using std::shared_ptr;
 using namespace dcpomatic;
 
 
 EmptyVideo::EmptyVideo (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist, DCPTime length)
 {
-       list<DCPTimePeriod> full;
+       list<DCPTimePeriod> full_left;
+       list<DCPTimePeriod> full_right;
+       list<DCPTimePeriod> full_both;
        for (auto i: playlist->content()) {
                if (i->video && i->video->use() && i->can_be_played() && i->paths_valid()) {
-                       full.push_back (DCPTimePeriod(i->position(), i->end(film)));
+                       auto period = DCPTimePeriod(i->position(), i->end(film));
+                       if (i->video->frame_type() == VideoFrameType::THREE_D_LEFT) {
+                               full_left.push_back (period);
+                       } else if (i->video->frame_type() == VideoFrameType::THREE_D_RIGHT) {
+                               full_right.push_back (period);
+                       } else {
+                               full_both.push_back (period);
+                       }
                }
        }
 
-       _periods = subtract (DCPTimePeriod(DCPTime(), length), coalesce(full));
+       auto const whole = DCPTimePeriod(DCPTime(), length);
+
+       auto empty_both = subtract(subtract(subtract({whole}, full_left), full_right), full_both);
+       auto empty_left = subtract(subtract(subtract({whole}, full_left), full_both), empty_both);
+       auto empty_right = subtract(subtract(subtract({whole}, full_right), full_both), empty_both);
+
+       for (auto left: empty_left) {
+               _periods.push_back (make_pair(left, Eyes::LEFT));
+       }
+
+       for (auto right: empty_right) {
+               _periods.push_back (make_pair(right, Eyes::RIGHT));
+       }
+
+       for (auto both: empty_both) {
+               _periods.push_back (make_pair(both, Eyes::BOTH));
+       }
+
+       _periods.sort([](std::pair<DCPTimePeriod, Eyes> const& a, std::pair<DCPTimePeriod, Eyes> const& b) {
+               return a.first < b.first;
+       });
 
        if (!_periods.empty()) {
-               _position = _periods.front().from;
+               _position = _periods.front().first.from;
        }
 }
 
@@ -62,26 +93,26 @@ EmptyVideo::set_position (DCPTime position)
        _position = position;
 
        for (auto i: _periods) {
-               if (i.contains(_position)) {
+               if (i.first.contains(_position)) {
                        return;
                }
        }
 
        for (auto i: _periods) {
-               if (i.from > _position) {
-                       _position = i.from;
+               if (i.first.from > _position) {
+                       _position = i.first.from;
                        return;
                }
        }
 }
 
 
-DCPTimePeriod
+pair<DCPTimePeriod, Eyes>
 EmptyVideo::period_at_position () const
 {
        for (auto i: _periods) {
-               if (i.contains(_position)) {
-                       return DCPTimePeriod (_position, i.to);
+               if (i.first.contains(_position)) {
+                       return make_pair(DCPTimePeriod(_position, i.first.to), i.second);
                }
        }
 
@@ -94,7 +125,7 @@ EmptyVideo::done () const
 {
        DCPTime latest;
        for (auto i: _periods) {
-               latest = max (latest, i.to);
+               latest = max (latest, i.first.to);
        }
 
        return _position >= latest;