WIP: more
[dcpomatic.git] / src / lib / player.cc
index ad23ea47dc2720fd6073c27057368e2075a0d9ff..7e915296ed1dfc06dc16b0535557671d85cebe53 100644 (file)
@@ -277,7 +277,11 @@ Player::setup_pieces_unlocked ()
                        }
                }
 
-               auto piece = make_shared<Piece>(_film, i, decoder, frc, _fast);
+               vector<Piece::Pair> content = {
+                       Piece::Pair(i, decoder)
+               };
+
+               auto piece = make_shared<Piece>(_film, content, frc, _fast);
                _pieces.push_back (piece);
 
                if (i->video) {
@@ -293,13 +297,10 @@ Player::setup_pieces_unlocked ()
                        piece->Audio.connect (bind(&Player::audio, this, weak_ptr<Piece>(piece), _1));
                }
 
-               piece->BitmapTextStart.connect (bind(&Player::bitmap_text_start, this, weak_ptr<Piece>(piece), _1));
-               piece->StringTextStart.connect (bind(&Player::string_text_start, this, weak_ptr<Piece>(piece), _1));
-               piece->TextStop.connect (bind(&Player::subtitle_stop, this, weak_ptr<Piece>(piece), _1));
-
-               if (decoder->atmos) {
-                       decoder->atmos->Data.connect (bind(&Player::atmos, this, weak_ptr<Piece>(piece), _1));
-               }
+               piece->BitmapTextStart.connect (bind(&Player::bitmap_text_start, this, piece, _1));
+               piece->StringTextStart.connect (bind(&Player::string_text_start, this, piece, _1));
+               piece->TextStop.connect (bind(&Player::subtitle_stop, this, piece, _1));
+               piece->Atmos.connect (bind(&Player::atmos, this, piece, _1));
        }
 
        for (auto i = _pieces.begin(); i != _pieces.end(); ++i) {
@@ -815,35 +816,20 @@ Player::video (weak_ptr<Piece> wp, PieceVideo video)
                return;
        }
 
-       if (!piece->use_video()) {
-               return;
-       }
-
-       auto frc = piece->frame_rate_change();
-       if (frc.skip && (video.frame % 2) == 1) {
-               return;
-       }
-
-       /* Time of the first frame we will emit */
-       DCPTime const time = piece->content_video_to_dcp (video.frame);
-       LOG_DEBUG_PLAYER("Received video frame %1 at %2", video.frame, to_string(time));
+       LOG_DEBUG_PLAYER("Received video frame %1 at %2", video.frame, to_string(video.time));
 
        /* Discard if it's before the content's period or the last accurate seek.  We can't discard
           if it's after the content's period here as in that case we still need to fill any gap between
           `now' and the end of the content's period.
        */
-       if (time < piece->position() || (_last_video_time && time < *_last_video_time)) {
-               return;
-       }
-
-       if (piece->ignore_video_at(time)) {
+       if (video.time < piece->position() || (_last_video_time && video.time < *_last_video_time)) {
                return;
        }
 
        /* Fill gaps that we discover now that we have some video which needs to be emitted.
           This is where we need to fill to.
        */
-       DCPTime fill_to = min (time, piece->end());
+       DCPTime fill_to = min (video.time, piece->end());
 
        if (_last_video_time) {
                DCPTime fill_from = max (*_last_video_time, piece->position());
@@ -894,7 +880,8 @@ Player::video (weak_ptr<Piece> wp, PieceVideo video)
 
        _last_video[wp] = piece->player_video (video, _video_container_size);
 
-       DCPTime t = time;
+       DCPTime t = video.time;
+       auto const frc = piece->frame_rate_change();
        for (int i = 0; i < frc.repeat; ++i) {
                if (t < piece->end()) {
                        emit_video (_last_video[wp], t);
@@ -905,68 +892,69 @@ Player::video (weak_ptr<Piece> wp, PieceVideo video)
 
 
 void
-Player::audio (weak_ptr<Piece> wp, PieceAudio piece_audio)
+Player::audio (weak_ptr<Piece> wp, PieceAudio audio)
 {
-       DCPOMATIC_ASSERT (piece_audio.audio->frames() > 0);
+       DCPOMATIC_ASSERT (audio.audio->frames() > 0);
 
        auto piece = wp.lock ();
        if (!piece) {
                return;
        }
 
-       int const rfr = piece->resampled_audio_frame_rate ();
+       LOG_DEBUG_PLAYER("Received audio at %1", to_string(audio.time));
 
-       /* Compute time in the DCP */
-       auto time = piece->resampled_audio_to_dcp (piece_audio.frame);
-       LOG_DEBUG_PLAYER("Received audio frame %1 at %2", piece_audio.frame, to_string(time));
+       /* The end of this block in the DCP */
+       int const rfr = piece->resampled_audio_frame_rate ();
+       auto end = audio.time + DCPTime::from_frames(audio.audio->frames(), rfr);
 
-       /* And the end of this block in the DCP */
-       auto end = time + DCPTime::from_frames(piece_audio.audio->frames(), rfr);
+       /* XXX: is this still necessary? don't the checks in Piece take care of this now?
+        * Maybe replace with some assertions & run tests.
+        */
 
        /* Remove anything that comes before the start or after the end of the content */
-       if (time < piece->position()) {
-               auto cut = discard_audio (piece_audio.audio, time, piece->position());
+       if (audio.time < piece->position()) {
+               auto cut = discard_audio (audio.audio, audio.time, piece->position());
                if (!cut.first) {
                        /* This audio is entirely discarded */
                        return;
                }
-               piece_audio.audio = cut.first;
-               time = cut.second;
-       } else if (time > piece->end()) {
+               audio.audio = cut.first;
+               audio.time = cut.second;
+       } else if (audio.time > piece->end()) {
                /* Discard it all */
                return;
        } else if (end > piece->end()) {
-               Frame const remaining_frames = DCPTime(piece->end() - time).frames_round(rfr);
+               Frame const remaining_frames = DCPTime(piece->end() - audio.time).frames_round(rfr);
                if (remaining_frames == 0) {
                        return;
                }
-               piece_audio.audio = make_shared<AudioBuffers>(piece_audio.audio, remaining_frames, 0);
+               audio.audio = make_shared<AudioBuffers>(audio.audio, remaining_frames, 0);
        }
 
-       DCPOMATIC_ASSERT (piece_audio.audio->frames() > 0);
+       DCPOMATIC_ASSERT (audio.audio->frames() > 0);
 
        /* Gain */
 
        if (piece->audio_gain() != 0) {
-               auto gain = make_shared<AudioBuffers>(piece_audio.audio);
+               auto gain = make_shared<AudioBuffers>(audio.audio);
                gain->apply_gain (piece->audio_gain());
-               piece_audio.audio = gain;
+               audio.audio = gain;
        }
 
        /* Remap */
 
-       piece_audio.audio = remap (piece_audio.audio, _film->audio_channels(), piece_audio.stream->mapping());
+       audio.audio = remap (audio.audio, _film->audio_channels(), audio.mapping);
 
        /* Process */
 
        if (_audio_processor) {
-               piece_audio.audio = _audio_processor->run (piece_audio.audio, _film->audio_channels ());
+               audio.audio = _audio_processor->run (audio.audio, _film->audio_channels());
        }
 
        /* Push */
 
-       _audio_merger.push (piece_audio.audio, time);
-       piece->set_last_push_end (piece_audio.stream, time + DCPTime::from_frames(piece_audio.audio->frames(), _film->audio_frame_rate()));
+       _audio_merger.push (audio.audio, audio.time);
+       piece->set_last_push_end (audio.stream, audio.time + DCPTime::from_frames(audio.audio->frames(), _film->audio_frame_rate()));
 }
 
 
@@ -1279,7 +1267,7 @@ Player::playlist () const
 
 
 void
-Player::atmos (weak_ptr<Piece>, ContentAtmos data)
+Player::atmos (weak_ptr<Piece>, PieceAtmos data)
 {
        Atmos (data.data, DCPTime::from_frames(data.frame, _film->video_frame_rate()), data.metadata);
 }