Fix empty (black) area calculations when video is set to not be used.
[dcpomatic.git] / src / lib / player.cc
index 3202c1b85dab30e7b9a0721abf983211402a2aba..4f81199a5a49847394ff58834786624bbec2d4a0 100644 (file)
@@ -83,10 +83,10 @@ int const PlayerProperty::PLAYLIST = 701;
 int const PlayerProperty::FILM_CONTAINER = 702;
 int const PlayerProperty::FILM_VIDEO_FRAME_RATE = 703;
 int const PlayerProperty::DCP_DECODE_REDUCTION = 704;
+int const PlayerProperty::PLAYBACK_LENGTH = 705;
 
-Player::Player (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist)
+Player::Player (shared_ptr<const Film> film)
        : _film (film)
-       , _playlist (playlist)
        , _suspended (0)
        , _ignore_video (false)
        , _ignore_audio (false)
@@ -97,13 +97,36 @@ Player::Player (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist
        , _play_referenced (false)
        , _audio_merger (_film->audio_frame_rate())
        , _shuffler (0)
+{
+       construct ();
+}
+
+Player::Player (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist_)
+       : _film (film)
+       , _playlist (playlist_)
+       , _suspended (0)
+       , _ignore_video (false)
+       , _ignore_audio (false)
+       , _ignore_text (false)
+       , _always_burn_open_subtitles (false)
+       , _fast (false)
+       , _tolerant (film->tolerant())
+       , _play_referenced (false)
+       , _audio_merger (_film->audio_frame_rate())
+       , _shuffler (0)
+{
+       construct ();
+}
+
+void
+Player::construct ()
 {
        _film_changed_connection = _film->Change.connect (bind (&Player::film_change, this, _1, _2));
        /* The butler must hear about this first, so since we are proxying this through to the butler we must
           be first.
        */
-       _playlist_change_connection = _playlist->Change.connect (bind (&Player::playlist_change, this, _1), boost::signals2::at_front);
-       _playlist_content_change_connection = _playlist->ContentChange.connect (bind(&Player::playlist_content_change, this, _1, _3, _4));
+       _playlist_change_connection = playlist()->Change.connect (bind (&Player::playlist_change, this, _1), boost::signals2::at_front);
+       _playlist_content_change_connection = playlist()->ContentChange.connect (bind(&Player::playlist_content_change, this, _1, _3, _4));
        set_video_container_size (_film->frame_size ());
 
        film_change (CHANGE_TYPE_DONE, Film::AUDIO_PROCESSOR);
@@ -124,10 +147,11 @@ Player::setup_pieces ()
        setup_pieces_unlocked ();
 }
 
+
 bool
 have_video (shared_ptr<const Content> content)
 {
-       return static_cast<bool>(content->video);
+       return static_cast<bool>(content->video) && content->video->use();
 }
 
 bool
@@ -139,6 +163,8 @@ have_audio (shared_ptr<const Content> content)
 void
 Player::setup_pieces_unlocked ()
 {
+       _playback_length = _playlist ? _playlist->length(_film) : _film->length();
+
        list<shared_ptr<Piece> > old_pieces = _pieces;
        _pieces.clear ();
 
@@ -146,7 +172,7 @@ Player::setup_pieces_unlocked ()
        _shuffler = new Shuffler();
        _shuffler->Video.connect(bind(&Player::video, this, _1, _2));
 
-       BOOST_FOREACH (shared_ptr<Content> i, _playlist->content ()) {
+       BOOST_FOREACH (shared_ptr<Content> i, playlist()->content()) {
 
                if (!i->paths_valid ()) {
                        continue;
@@ -237,15 +263,12 @@ Player::setup_pieces_unlocked ()
                }
        }
 
-       _black = Empty (_film, _playlist, bind(&have_video, _1));
-       _silent = Empty (_film, _playlist, bind(&have_audio, _1));
+       _black = Empty (_film, playlist(), bind(&have_video, _1), _playback_length);
+       _silent = Empty (_film, playlist(), bind(&have_audio, _1), _playback_length);
 
        _last_video_time = DCPTime ();
        _last_video_eyes = EYES_BOTH;
        _last_audio_time = DCPTime ();
-
-       /* Cached value to save recalculating it on every ::pass */
-       _film_length = _film->length ();
 }
 
 void
@@ -498,7 +521,7 @@ Player::get_reel_assets ()
 
        list<ReferencedReelAsset> a;
 
-       BOOST_FOREACH (shared_ptr<Content> i, _playlist->content ()) {
+       BOOST_FOREACH (shared_ptr<Content> i, playlist()->content()) {
                shared_ptr<DCPContent> j = dynamic_pointer_cast<DCPContent> (i);
                if (!j) {
                        continue;
@@ -566,15 +589,14 @@ bool
 Player::pass ()
 {
        boost::mutex::scoped_lock lm (_mutex);
-       DCPOMATIC_ASSERT (_film_length);
 
        if (_suspended) {
                /* We can't pass in this state */
                return false;
        }
 
-       if (*_film_length == DCPTime()) {
-               /* Special case of an empty Film; just give one black frame */
+       if (_playback_length == DCPTime()) {
+               /* Special; just give one black frame */
                emit_video (black_player_video_frame(EYES_BOTH), DCPTime());
                return true;
        }
@@ -680,7 +702,7 @@ Player::pass ()
        /* Work out the time before which the audio is definitely all here.  This is the earliest last_push_end of one
           of our streams, or the position of the _silent.
        */
-       DCPTime pull_to = *_film_length;
+       DCPTime pull_to = _playback_length;
        for (map<AudioStreamPtr, StreamState>::const_iterator i = _stream_states.begin(); i != _stream_states.end(); ++i) {
                if (!i->second.piece->done && i->second.last_push_end < pull_to) {
                        pull_to = i->second.last_push_end;
@@ -842,9 +864,7 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
                        video.image,
                        piece->content->video->crop (),
                        piece->content->video->fade (_film, video.frame),
-                       piece->content->video->scale().size (
-                               piece->content->video, _video_container_size, _film->frame_size ()
-                               ),
+                       scale_for_display(piece->content->video->scaled_size(_film->frame_size()), _video_container_size, _film->frame_size()),
                        _video_container_size,
                        video.eyes,
                        video.part,
@@ -1234,3 +1254,11 @@ Player::content_time_to_dcp (shared_ptr<Content> content, ContentTime t)
        /* We couldn't find this content; perhaps things are being changed over */
        return optional<DCPTime>();
 }
+
+
+shared_ptr<const Playlist>
+Player::playlist () const
+{
+       return _playlist ? _playlist : _film->playlist();
+}
+