Previously the code did not account for referenced audio, so far
authorCarl Hetherington <cth@carlh.net>
Fri, 29 Dec 2017 01:11:22 +0000 (01:11 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 29 Dec 2017 01:11:22 +0000 (01:11 +0000)
as I can see.  It decided which reel to write new audio to based on
how many frames had been written to the current reel; this makes
no sense for referred reels for which the player will emit no audio.

This code looks at the audio timestamp instead.

src/lib/dcp_encoder.cc
src/lib/reel_writer.cc
src/lib/reel_writer.h
src/lib/writer.cc
src/lib/writer.h

index 81464c8dc9c7c43f9f810b3b32bf967bac52bed1..76bfba5a2f19f0efd54b6f2a7bdab162fa67ac0f 100644 (file)
@@ -121,11 +121,10 @@ DCPEncoder::video (shared_ptr<PlayerVideo> data, DCPTime time)
        _j2k_encoder->encode (data, time);
 }
 
-/** The audio data passed into this method must be contiguous and start from the last accurate seek time */
 void
 DCPEncoder::audio (shared_ptr<AudioBuffers> data, DCPTime time)
 {
-       _writer->write (data);
+       _writer->write (data, time);
 
        shared_ptr<Job> job = _job.lock ();
        DCPOMATIC_ASSERT (job);
index 1e730259f5dd63d4be2ed77234d674db67998a12..c560909a9f5c1aa2d189a8b3dccc23a3fcd3a313 100644 (file)
@@ -69,7 +69,6 @@ ReelWriter::ReelWriter (
        , _period (period)
        , _last_written_video_frame (-1)
        , _last_written_eyes (EYES_RIGHT)
-       , _total_written_audio_frames (0)
        , _reel_index (reel_index)
        , _reel_count (reel_count)
        , _content_summary (content_summary)
@@ -534,8 +533,6 @@ ReelWriter::write (shared_ptr<const AudioBuffers> audio)
        if (audio) {
                _sound_asset_writer->write (audio->data(), audio->frames());
        }
-
-       _total_written_audio_frames += audio->frames ();
 }
 
 void
index edf6c081e955bfff863bda6286652404ce445bba..c0e98f6ebf89b7bd2bdd06858c2cd605995c1054 100644 (file)
@@ -72,10 +72,6 @@ public:
                return _period;
        }
 
-       int total_written_audio_frames () const {
-               return _total_written_audio_frames;
-       }
-
        int last_written_video_frame () const {
                return _last_written_video_frame;
        }
@@ -107,8 +103,6 @@ private:
        /** the index of the last written video frame within the reel */
        int _last_written_video_frame;
        Eyes _last_written_eyes;
-       /** the number of audio frames that have been written to the reel */
-       int _total_written_audio_frames;
        /** index of this reel within the DCP (starting from 0) */
        int _reel_index;
        /** number of reels in the DCP */
index 3f0c687c24c7fd25bdd63e582354cf974d565475..6295058b81f0133ad922ab14a4f4c1712d0a4fd2 100644 (file)
@@ -231,36 +231,44 @@ Writer::fake_write (Frame frame, Eyes eyes)
 }
 
 /** 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).
+ *  @param audio Audio data.
+ *  @param time Time of this data within the DCP.
  *  This method is not thread safe.
  */
 void
-Writer::write (shared_ptr<const AudioBuffers> audio)
+Writer::write (shared_ptr<const AudioBuffers> audio, DCPTime const time)
 {
+       DCPOMATIC_ASSERT (audio);
+
+       int const afr = _film->audio_frame_rate();
+
+       DCPTime const end = time + DCPTime::from_frames(audio->frames(), afr);
+
        /* The audio we get might span a reel boundary, and if so we have to write it in bits */
 
-       int32_t offset = 0;
-       while (offset < audio->frames ()) {
+       DCPTime t = time;
+       while (t < end) {
 
                if (_audio_reel == _reels.end ()) {
                        /* This audio is off the end of the last reel; ignore it */
                        return;
                }
 
-               int32_t const remaining = audio->frames() - offset;
-               int32_t const reel_space = _audio_reel->period().duration().frames_floor(_film->audio_frame_rate()) - _audio_reel->total_written_audio_frames();
-
-               if (remaining <= reel_space) {
+               if (end <= _audio_reel->period().to) {
                        /* Easy case: we can write all the audio to this reel */
                        _audio_reel->write (audio);
-                       offset += remaining;
+                       t = end;
                } else {
                        /* Write the part we can */
-                       shared_ptr<AudioBuffers> part (new AudioBuffers (audio->channels(), reel_space));
-                       part->copy_from (audio.get(), reel_space, offset, 0);
-                       _audio_reel->write (part);
+                       DCPTime const this_reel = _audio_reel->period().to - t;
+                       Frame const this_reel_frames = this_reel.frames_ceil(afr);
+                       if (this_reel_frames) {
+                               shared_ptr<AudioBuffers> part (new AudioBuffers (audio->channels(), this_reel_frames));
+                               part->copy_from (audio.get(), this_reel_frames, DCPTime(t - time).frames_ceil(afr), 0);
+                               _audio_reel->write (part);
+                       }
                        ++_audio_reel;
-                       offset += reel_space;
+                       t += this_reel;
                }
        }
 }
index cb1bdc5cc3fbc44a6a08db16dd83b5b2ed32639e..ec7b9880417c9363d13f7d6459b95124afb594f5 100644 (file)
@@ -103,7 +103,7 @@ public:
        void fake_write (Frame, Eyes);
        bool can_repeat (Frame) const;
        void repeat (Frame, Eyes);
-       void write (boost::shared_ptr<const AudioBuffers>);
+       void write (boost::shared_ptr<const AudioBuffers>, DCPTime time);
        void write (PlayerSubtitles subs, DCPTimePeriod period);
        void write (std::list<boost::shared_ptr<Font> > fonts);
        void write (ReferencedReelAsset asset);