Use EnumIndexedVector in Player.
[dcpomatic.git] / src / lib / player.cc
index c3fee45b47bb17f84c5f25414d1852680886a9ce..7e3a1bdcf15e072ce740236fe0c30755aae529d3 100644 (file)
@@ -47,7 +47,6 @@
 #include "playlist.h"
 #include "ratio.h"
 #include "raw_image_proxy.h"
-#include "referenced_reel_asset.h"
 #include "render_text.h"
 #include "shuffler.h"
 #include "text_content.h"
@@ -148,14 +147,6 @@ Player::construct ()
 }
 
 
-void
-Player::setup_pieces ()
-{
-       boost::mutex::scoped_lock lm (_mutex);
-       setup_pieces_unlocked ();
-}
-
-
 bool
 have_video (shared_ptr<const Content> content)
 {
@@ -171,8 +162,10 @@ have_audio (shared_ptr<const Content> content)
 
 
 void
-Player::setup_pieces_unlocked ()
+Player::setup_pieces ()
 {
+       boost::mutex::scoped_lock lm (_mutex);
+
        _playback_length = _playlist ? _playlist->length(_film) : _film->length();
 
        auto old_pieces = _pieces;
@@ -314,10 +307,9 @@ Player::playlist_content_change (ChangeType type, int property, bool frequent)
 {
        if (property == VideoContentProperty::CROP) {
                if (type == ChangeType::DONE) {
-                       auto const vcs = video_container_size();
                        boost::mutex::scoped_lock lm (_mutex);
                        for (auto const& i: _delay) {
-                               i.first->reset_metadata (_film, vcs);
+                               i.first->reset_metadata(_film, _video_container_size);
                        }
                }
        } else {
@@ -353,7 +345,7 @@ Player::set_video_container_size (dcp::Size s)
        _video_container_size = s;
 
        {
-               boost::mutex::scoped_lock lm (_mutex);
+               boost::mutex::scoped_lock lm(_black_image_mutex);
                _black_image = make_shared<Image>(AV_PIX_FMT_RGB24, _video_container_size, Image::Alignment::PADDED);
                _black_image->make_black ();
        }
@@ -407,6 +399,8 @@ Player::film_change (ChangeType type, Film::Property p)
 shared_ptr<PlayerVideo>
 Player::black_player_video_frame (Eyes eyes) const
 {
+       boost::mutex::scoped_lock lm(_black_image_mutex);
+
        return std::make_shared<PlayerVideo> (
                std::make_shared<const RawImageProxy>(_black_image),
                Crop(),
@@ -554,98 +548,6 @@ Player::set_play_referenced ()
 }
 
 
-static void
-maybe_add_asset (list<ReferencedReelAsset>& a, shared_ptr<dcp::ReelAsset> r, Frame reel_trim_start, Frame reel_trim_end, DCPTime from, int const ffr)
-{
-       DCPOMATIC_ASSERT (r);
-       r->set_entry_point (r->entry_point().get_value_or(0) + reel_trim_start);
-       r->set_duration (r->actual_duration() - reel_trim_start - reel_trim_end);
-       if (r->actual_duration() > 0) {
-               a.push_back (
-                       ReferencedReelAsset(r, DCPTimePeriod(from, from + DCPTime::from_frames(r->actual_duration(), ffr)))
-                       );
-       }
-}
-
-
-list<ReferencedReelAsset>
-Player::get_reel_assets ()
-{
-       /* Does not require a lock on _mutex as it's only called from DCPEncoder */
-
-       list<ReferencedReelAsset> reel_assets;
-
-       for (auto content: playlist()->content()) {
-               auto dcp = dynamic_pointer_cast<DCPContent>(content);
-               if (!dcp) {
-                       continue;
-               }
-
-               if (!dcp->reference_video() && !dcp->reference_audio() && !dcp->reference_text(TextType::OPEN_SUBTITLE) && !dcp->reference_text(TextType::CLOSED_CAPTION)) {
-                       continue;
-               }
-
-               scoped_ptr<DCPDecoder> decoder;
-               try {
-                       decoder.reset (new DCPDecoder(_film, dcp, false, false, shared_ptr<DCPDecoder>()));
-               } catch (...) {
-                       return reel_assets;
-               }
-
-               auto const frame_rate = _film->video_frame_rate();
-               DCPOMATIC_ASSERT (dcp->video_frame_rate());
-               /* We should only be referencing if the DCP rate is the same as the film rate */
-               DCPOMATIC_ASSERT (std::round(dcp->video_frame_rate().get()) == frame_rate);
-
-               Frame const trim_start = dcp->trim_start().frames_round(frame_rate);
-               Frame const trim_end = dcp->trim_end().frames_round(frame_rate);
-
-               /* position in the asset from the start */
-               int64_t offset_from_start = 0;
-               /* position i the asset from the end */
-               int64_t offset_from_end = 0;
-               for (auto reel: decoder->reels()) {
-                       /* Assume that main picture duration is the length of the reel */
-                       offset_from_end += reel->main_picture()->actual_duration();
-               }
-
-               for (auto reel: decoder->reels()) {
-
-                       /* Assume that main picture duration is the length of the reel */
-                       int64_t const reel_duration = reel->main_picture()->actual_duration();
-
-                       /* See doc/design/trim_reels.svg */
-                       Frame const reel_trim_start = min(reel_duration, max(int64_t(0), trim_start - offset_from_start));
-                       Frame const reel_trim_end =   min(reel_duration, max(int64_t(0), reel_duration - (offset_from_end - trim_end)));
-
-                       auto const from = content->position() + std::max(DCPTime(), DCPTime::from_frames(offset_from_start - trim_start, frame_rate));
-                       if (dcp->reference_video()) {
-                               maybe_add_asset (reel_assets, reel->main_picture(), reel_trim_start, reel_trim_end, from, frame_rate);
-                       }
-
-                       if (dcp->reference_audio()) {
-                               maybe_add_asset (reel_assets, reel->main_sound(), reel_trim_start, reel_trim_end, from, frame_rate);
-                       }
-
-                       if (dcp->reference_text(TextType::OPEN_SUBTITLE)) {
-                               maybe_add_asset (reel_assets, reel->main_subtitle(), reel_trim_start, reel_trim_end, from, frame_rate);
-                       }
-
-                       if (dcp->reference_text(TextType::CLOSED_CAPTION)) {
-                               for (auto caption: reel->closed_captions()) {
-                                       maybe_add_asset (reel_assets, caption, reel_trim_start, reel_trim_end, from, frame_rate);
-                               }
-                       }
-
-                       offset_from_start += reel_duration;
-                       offset_from_end -= reel_duration;
-               }
-       }
-
-       return reel_assets;
-}
-
-
 bool
 Player::pass ()
 {
@@ -657,7 +559,7 @@ Player::pass ()
                return false;
        }
 
-       if (_playback_length == DCPTime()) {
+       if (_playback_length.load() == DCPTime()) {
                /* Special; just give one black frame */
                emit_video (black_player_video_frame(Eyes::BOTH), DCPTime());
                return true;
@@ -795,7 +697,7 @@ Player::pass ()
                }
        }
 
-       auto pull_to = _playback_length;
+       auto pull_to = _playback_length.load();
        for (auto const& i: alive_stream_states) {
                if (!i.second.piece->done && i.second.last_push_end < pull_to) {
                        pull_to = i.second.last_push_end;
@@ -858,7 +760,7 @@ Player::open_subtitles_for_frame (DCPTime time) const
 
        for (
                auto j:
-               _active_texts[static_cast<int>(TextType::OPEN_SUBTITLE)].get_burnt(DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), _always_burn_open_subtitles)
+               _active_texts[TextType::OPEN_SUBTITLE].get_burnt(DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), _always_burn_open_subtitles)
                ) {
 
                /* Bitmap subtitles */
@@ -1149,7 +1051,7 @@ Player::bitmap_text_start (weak_ptr<Piece> weak_piece, weak_ptr<const TextConten
        }
 
        DCPTime from(content_time_to_dcp(piece, subtitle.from()));
-       _active_texts[static_cast<int>(content->type())].add_from(weak_content, ps, from);
+       _active_texts[content->type()].add_from(weak_content, ps, from);
 }
 
 
@@ -1197,7 +1099,7 @@ Player::plain_text_start (weak_ptr<Piece> weak_piece, weak_ptr<const TextContent
                ps.string.push_back (s);
        }
 
-       _active_texts[static_cast<int>(content->type())].add_from(weak_content, ps, from);
+       _active_texts[content->type()].add_from(weak_content, ps, from);
 }
 
 
@@ -1213,7 +1115,7 @@ Player::subtitle_stop (weak_ptr<Piece> weak_piece, weak_ptr<const TextContent> w
                return;
        }
 
-       if (!_active_texts[static_cast<int>(content->type())].have(weak_content)) {
+       if (!_active_texts[content->type()].have(weak_content)) {
                return;
        }
 
@@ -1228,7 +1130,7 @@ Player::subtitle_stop (weak_ptr<Piece> weak_piece, weak_ptr<const TextContent> w
                return;
        }
 
-       auto from = _active_texts[static_cast<int>(content->type())].add_to(weak_content, dcp_to);
+       auto from = _active_texts[content->type()].add_to(weak_content, dcp_to);
 
        bool const always = (content->type() == TextType::OPEN_SUBTITLE && _always_burn_open_subtitles);
        if (content->use() && !always && !content->burn()) {
@@ -1259,9 +1161,7 @@ Player::seek (DCPTime time, bool accurate)
        }
 
        _audio_merger.clear ();
-       for (int i = 0; i < static_cast<int>(TextType::COUNT); ++i) {
-               _active_texts[i].clear ();
-       }
+       std::for_each(_active_texts.begin(), _active_texts.end(), [](ActiveText& a) { a.clear(); });
 
        for (auto i: _pieces) {
                if (time < i->content->position()) {
@@ -1336,9 +1236,7 @@ void
 Player::do_emit_video (shared_ptr<PlayerVideo> pv, DCPTime time)
 {
        if (pv->eyes() == Eyes::BOTH || pv->eyes() == Eyes::RIGHT) {
-               for (int i = 0; i < static_cast<int>(TextType::COUNT); ++i) {
-                       _active_texts[i].clear_before (time);
-               }
+               std::for_each(_active_texts.begin(), _active_texts.end(), [time](ActiveText& a) { a.clear_before(time); });
        }
 
        auto subtitles = open_subtitles_for_frame (time);
@@ -1427,7 +1325,7 @@ Player::set_dcp_decode_reduction (optional<int> reduction)
 
 
 optional<DCPTime>
-Player::content_time_to_dcp (shared_ptr<const Content> content, ContentTime t)
+Player::content_time_to_dcp (shared_ptr<const Content> content, ContentTime t) const
 {
        boost::mutex::scoped_lock lm (_mutex);
 
@@ -1443,7 +1341,7 @@ Player::content_time_to_dcp (shared_ptr<const Content> content, ContentTime t)
 
 
 optional<ContentTime>
-Player::dcp_to_content_time (shared_ptr<const Content> content, DCPTime t)
+Player::dcp_to_content_time (shared_ptr<const Content> content, DCPTime t) const
 {
        boost::mutex::scoped_lock lm (_mutex);