Fix pull timing; fix units of ReelWriter::total_written_audio_frames.
authorCarl Hetherington <cth@carlh.net>
Wed, 22 Feb 2017 13:40:17 +0000 (13:40 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 19 Apr 2017 22:04:32 +0000 (23:04 +0100)
src/lib/player.cc
src/lib/player.h
src/lib/reel_writer.cc
src/lib/transcoder.cc
src/lib/writer.cc

index 7b1b08250b5edb3ec7f16ee61613a0af22bca03f..eeeef2cb3ed4006170127a7d647a186c056d029f 100644 (file)
@@ -548,24 +548,14 @@ Player::pass ()
 
        /* Emit any audio that is ready */
 
-       optional<DCPTime> earliest_audio;
-       BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
-               if (i->decoder->audio) {
-                       DCPTime t = i->content->position()
-                               + DCPTime (i->decoder->audio->position(), i->frc)
-                               + DCPTime::from_seconds (i->content->audio->delay() / 1000.0);
-
-                       if (t < DCPTime()) {
-                               t = DCPTime();
-                       }
-
-                       if (!earliest_audio || t < *earliest_audio) {
-                               earliest_audio = t;
-                       }
+       DCPTime pull_from = _playlist->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_from) {
+                       pull_from = i->second.last_push_end;
                }
        }
 
-       pair<shared_ptr<AudioBuffers>, DCPTime> audio = _audio_merger.pull (earliest_audio.get_value_or(DCPTime()));
+       pair<shared_ptr<AudioBuffers>, DCPTime> audio = _audio_merger.pull (pull_from);
        if (audio.first->frames() > 0) {
                DCPOMATIC_ASSERT (audio.second >= _last_audio_time);
                DCPTime t = _last_audio_time;
@@ -751,6 +741,12 @@ Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_a
        }
 
        _audio_merger.push (content_audio.audio, time);
+
+       if (_stream_states.find (stream) == _stream_states.end ()) {
+               _stream_states[stream] = StreamState (piece, time);
+       } else {
+               _stream_states[stream].last_push_end = time + DCPTime::from_frames (content_audio.audio->frames(), _film->audio_frame_rate());
+       }
 }
 
 void
index c891ee85c0371f01dd97b8b72cb4bc474f2336ce..69149d0393aefe2b8863eca73f0661fe8d34f37f 100644 (file)
@@ -140,6 +140,20 @@ private:
        AudioMerger _audio_merger;
        DCPTime _last_audio_time;
 
+       class StreamState {
+       public:
+               StreamState () {}
+
+               StreamState (boost::shared_ptr<Piece> p, DCPTime l)
+                       : piece(p)
+                       , last_push_end(l)
+               {}
+
+               boost::shared_ptr<Piece> piece;
+               DCPTime last_push_end;
+       };
+       std::map<AudioStreamPtr, StreamState> _stream_states;
+
        std::list<std::pair<PlayerSubtitles, DCPTimePeriod> > _subtitles;
 
        boost::shared_ptr<AudioProcessor> _audio_processor;
index 5dd9f5d2598f3b9bb566b0ea89f18b317ef8437c..e008bf6311ae5acbcbcfa8a1b1d41bbfb75aa225 100644 (file)
@@ -480,7 +480,7 @@ ReelWriter::write (shared_ptr<const AudioBuffers> audio)
                _sound_asset_writer->write (audio->data(), audio->frames());
        }
 
-       ++_total_written_audio_frames;
+       _total_written_audio_frames += audio->frames ();
 }
 
 void
index de2fb1d3388b73d94b1b5889c8b91b7d153083be..e2bbca98e2fa2ff879dc5c3644f406231025f8fe 100644 (file)
@@ -115,6 +115,7 @@ Transcoder::video (shared_ptr<PlayerVideo> data, DCPTime time)
 void
 Transcoder::audio (shared_ptr<AudioBuffers> data, DCPTime time)
 {
+       cout << "tx receives " << data->frames() << " @ " << to_string(time) << "\n";
        _writer->write (data);
 
        shared_ptr<Job> job = _job.lock ();
index 88925cbbdbeb8596c1a809faf45884dad913b586..74e5e3ec081da7ded20a1da9946aa5cc3996b75e 100644 (file)
@@ -229,7 +229,7 @@ Writer::fake_write (Frame frame, Eyes eyes)
        _empty_condition.notify_all ();
 }
 
-/** Write one video frame's worth of audio frames to the DCP.
+/** Write some audio frames to the DCP.
  *  @param audio Audio data or 0 if there is no audio to be written here (i.e. it is referenced).
  *  This method is not thread safe.
  */
@@ -243,8 +243,7 @@ Writer::write (shared_ptr<const AudioBuffers> audio)
 
        _audio_reel->write (audio);
 
-       /* written is in video frames, not audio frames */
-       if (_audio_reel->total_written_audio_frames() >= _audio_reel->period().duration().frames_floor (_film->video_frame_rate())) {
+       if (_audio_reel->total_written_audio_frames() >= _audio_reel->period().duration().frames_floor (_film->audio_frame_rate())) {
                ++_audio_reel;
        }
 }