Seemingly basically working butler for video.
[dcpomatic.git] / src / lib / player.cc
index 076bd61bcee9e597d00577dde33c6d3af6fa58a3..a6df63ac0377ab6e42ecaeb476bb990d17d33c1a 100644 (file)
@@ -226,10 +226,16 @@ Player::playlist_content_changed (weak_ptr<Content> w, int property, bool freque
 void
 Player::set_video_container_size (dcp::Size s)
 {
+       if (s == _video_container_size) {
+               return;
+       }
+
        _video_container_size = s;
 
        _black_image.reset (new Image (AV_PIX_FMT_RGB24, _video_container_size, true));
        _black_image->make_black ();
+
+       Changed (false);
 }
 
 void
@@ -362,7 +368,7 @@ DCPTime
 Player::resampled_audio_to_dcp (shared_ptr<const Piece> piece, Frame f) const
 {
        /* See comment in dcp_to_content_video */
-       DCPTime const d = DCPTime::from_frames (f, _film->audio_frame_rate()) - DCPTime (piece->content->trim_start (), piece->frc);
+       DCPTime const d = DCPTime::from_frames (f, _film->audio_frame_rate()) - DCPTime (piece->content->trim_start(), piece->frc);
        return max (DCPTime (), d + piece->content->position ());
 }
 
@@ -679,7 +685,11 @@ Player::audio_flush (shared_ptr<Piece> piece, AudioStreamPtr stream)
        shared_ptr<AudioContent> content = piece->content->audio;
        DCPOMATIC_ASSERT (content);
 
-       shared_ptr<Resampler> r = resampler (content, stream);
+       shared_ptr<Resampler> r = resampler (content, stream, false);
+       if (!r) {
+               return;
+       }
+
        pair<shared_ptr<const AudioBuffers>, Frame> ro = r->flush ();
        ContentAudio content_audio;
        content_audio.audio = ro.first;
@@ -750,18 +760,18 @@ Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_a
 
        /* Resample */
        if (stream->frame_rate() != content->resampled_frame_rate()) {
-               shared_ptr<Resampler> r = resampler (content, stream);
+               shared_ptr<Resampler> r = resampler (content, stream, true);
                pair<shared_ptr<const AudioBuffers>, Frame> ro = r->run (content_audio.audio, content_audio.frame);
                content_audio.audio = ro.first;
                content_audio.frame = ro.second;
        }
 
-       /* XXX: end-trimming used to be checked here */
-
        /* Compute time in the DCP */
        DCPTime time = resampled_audio_to_dcp (piece, content_audio.frame) + DCPTime::from_seconds (content->delay() / 1000.0);
+       /* And the end of this block in the DCP */
+       DCPTime end = time + DCPTime::from_frames(content_audio.audio->frames(), content->resampled_frame_rate());
 
-       /* Remove anything that comes before the start of the content */
+       /* Remove anything that comes before the start or after the end of the content */
        if (time < piece->content->position()) {
                DCPTime const discard_time = piece->content->position() - time;
                Frame discard_frames = discard_time.frames_round(_film->audio_frame_rate());
@@ -774,6 +784,14 @@ Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_a
                cut->copy_from (content_audio.audio.get(), remaining_frames, discard_frames, 0);
                content_audio.audio = cut;
                time += discard_time;
+       } else if (time > piece->content->end()) {
+               /* Discard it all */
+               return;
+       } else if (end > piece->content->end()) {
+               Frame const remaining_frames = DCPTime(piece->content->end() - time).frames_round(_film->audio_frame_rate());
+               shared_ptr<AudioBuffers> cut (new AudioBuffers (content_audio.audio->channels(), remaining_frames));
+               cut->copy_from (content_audio.audio.get(), remaining_frames, 0, 0);
+               content_audio.audio = cut;
        }
 
        audio_transform (content, stream, content_audio, time);
@@ -876,13 +894,17 @@ Player::seek (DCPTime time, bool accurate)
 }
 
 shared_ptr<Resampler>
-Player::resampler (shared_ptr<const AudioContent> content, AudioStreamPtr stream)
+Player::resampler (shared_ptr<const AudioContent> content, AudioStreamPtr stream, bool create)
 {
        ResamplerMap::const_iterator i = _resamplers.find (make_pair (content, stream));
        if (i != _resamplers.end ()) {
                return i->second;
        }
 
+       if (!create) {
+               return shared_ptr<Resampler> ();
+       }
+
        LOG_GENERAL (
                "Creating new resampler from %1 to %2 with %3 channels",
                stream->frame_rate(),