Several fixes to audio.
authorCarl Hetherington <cth@carlh.net>
Sun, 9 Apr 2017 21:43:56 +0000 (22:43 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 19 Apr 2017 22:04:32 +0000 (23:04 +0100)
src/lib/butler.cc
src/lib/player.cc
src/lib/player.h
src/lib/video_ring_buffers.cc
src/wx/film_viewer.cc

index 01c1ec4f8e097bd668ec002e455f7a12a9ce6ea7..ea195b5d55b2fe2ed4581fe60687687f4cbea0ba 100644 (file)
@@ -33,6 +33,8 @@ using boost::optional;
 
 /** Video readahead in frames */
 #define VIDEO_READAHEAD 10
+/** Audio readahead in frames */
+#define AUDIO_READAHEAD 48000
 
 Butler::Butler (weak_ptr<const Film> film, shared_ptr<Player> player, AudioMapping audio_mapping, int audio_channels)
        : _film (film)
@@ -69,7 +71,7 @@ try
                boost::mutex::scoped_lock lm (_mutex);
 
                /* Wait until we have something to do */
-               while ((_video.size() >= VIDEO_READAHEAD && !_pending_seek_position) || _stop_thread) {
+               while ((_video.size() >= VIDEO_READAHEAD && _audio.size() >= AUDIO_READAHEAD && !_pending_seek_position) || _stop_thread) {
                        _summon.wait (lm);
                }
 
@@ -79,11 +81,11 @@ try
                        _pending_seek_position = optional<DCPTime> ();
                }
 
-               /* Fill _video.  Don't try to carry on if a pending seek appears
+               /* Fill _video and _audio.  Don't try to carry on if a pending seek appears
                   while lm is unlocked, as in that state nothing will be added to
-                  _video.
+                  _video/_audio.
                */
-               while (_video.size() < VIDEO_READAHEAD && !_pending_seek_position && !_stop_thread) {
+               while ((_video.size() < VIDEO_READAHEAD || _audio.size() < AUDIO_READAHEAD) && !_pending_seek_position && !_stop_thread) {
                        lm.unlock ();
                        if (_player->pass ()) {
                                _finished = true;
@@ -145,7 +147,15 @@ Butler::video (shared_ptr<PlayerVideo> video, DCPTime time)
 void
 Butler::audio (shared_ptr<AudioBuffers> audio, DCPTime time)
 {
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               if (_pending_seek_position) {
+                       /* Don't store any audio while a seek is pending */
+                       return;
+               }
+       }
 
+       _audio.put (audio, time);
 }
 
 void
index a6df63ac0377ab6e42ecaeb476bb990d17d33c1a..3c2b3478e748bec391e449508f237b94de8b7dec 100644 (file)
@@ -551,11 +551,15 @@ Player::pass ()
        if (!earliest) {
                /* No more content; fill up with silent black */
                DCPTimePeriod remaining_video (DCPTime(), _playlist->length());
-               if (_last_time) {
-                       remaining_video.from = _last_time.get() + one_video_frame();
+               if (_last_video_time) {
+                       remaining_video.from = _last_video_time.get() + one_video_frame();
                }
                fill_video (remaining_video);
-               fill_audio (DCPTimePeriod (_last_audio_time, _playlist->length()));
+               DCPTimePeriod remaining_audio (DCPTime(), _playlist->length());
+               if (_last_audio_time) {
+                       remaining_audio.from = _last_audio_time.get();
+               }
+               fill_audio (remaining_audio);
                return true;
        }
 
@@ -578,8 +582,10 @@ Player::pass ()
 
        list<pair<shared_ptr<AudioBuffers>, DCPTime> > audio = _audio_merger.pull (pull_from);
        for (list<pair<shared_ptr<AudioBuffers>, DCPTime> >::iterator i = audio.begin(); i != audio.end(); ++i) {
-               DCPOMATIC_ASSERT (i->second >= _last_audio_time);
-               fill_audio (DCPTimePeriod (_last_audio_time, i->second));
+               DCPOMATIC_ASSERT (!_last_audio_time || i->second >= _last_audio_time.get());
+               if (_last_audio_time) {
+                       fill_audio (DCPTimePeriod (_last_audio_time.get(), i->second));
+               }
                Audio (i->first, i->second);
                _last_audio_time = i->second + DCPTime::from_frames(i->first->frames(), _film->audio_frame_rate());
        }
@@ -638,8 +644,8 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
 
        /* Fill gaps */
 
-       if (_last_time) {
-               fill_video (DCPTimePeriod (_last_time.get() + one_video_frame(), time));
+       if (_last_video_time) {
+               fill_video (DCPTimePeriod (_last_video_time.get() + one_video_frame(), time));
        }
 
        _last_video.reset (
@@ -661,9 +667,9 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
                _last_video->set_subtitle (subtitles.get ());
        }
 
-       _last_time = time;
+       _last_video_time = time;
 
-       Video (_last_video, *_last_time);
+       Video (_last_video, *_last_video_time);
 
        /* Discard any subtitles we no longer need */
 
@@ -887,9 +893,11 @@ Player::seek (DCPTime time, bool accurate)
        }
 
        if (accurate) {
-               _last_time = time - one_video_frame ();
+               _last_video_time = time - one_video_frame ();
+               _last_audio_time = time;
        } else {
-               _last_time = optional<DCPTime> ();
+               _last_video_time = optional<DCPTime> ();
+               _last_audio_time = optional<DCPTime> ();
        }
 }
 
index 6e9c9d7ee32f243e46db45c5b6c48b0deab00342..ea07e1fc8bb0e0503168fd71c654688e9696f98c 100644 (file)
@@ -139,11 +139,11 @@ private:
 
        /** Last PlayerVideo that was emitted */
        boost::shared_ptr<PlayerVideo> _last_video;
-       /** Time of the last thing we emitted, or the last seek time */
-       boost::optional<DCPTime> _last_time;
+       /** Time of the last video we emitted, or the last seek time */
+       boost::optional<DCPTime> _last_video_time;
 
        AudioMerger _audio_merger;
-       DCPTime _last_audio_time;
+       boost::optional<DCPTime> _last_audio_time;
 
        class StreamState {
        public:
index e81605732dd323ea240e501f57af299609d12987..a8688a1cd7f6d246562f63e90780cdda72600563 100644 (file)
@@ -34,7 +34,6 @@ using boost::optional;
 void
 VideoRingBuffers::put (shared_ptr<PlayerVideo> frame, DCPTime time)
 {
-       cout << "put " << to_string(time) << "\n";
        boost::mutex::scoped_lock lm (_mutex);
        _data.push_back (make_pair (frame, time));
 }
@@ -44,11 +43,9 @@ VideoRingBuffers::get ()
 {
        boost::mutex::scoped_lock lm (_mutex);
        if (_data.empty ()) {
-               cout << "get: no data.\n";
                return make_pair(shared_ptr<PlayerVideo>(), DCPTime());
        }
        pair<shared_ptr<PlayerVideo>, DCPTime> const r = _data.front ();
-       cout << "get: here we go! " << to_string(r.second) << "\n";
        _data.pop_front ();
        return r;
 }
index 3d9ec036b2ebb97044fe889a8d5bb25a1a038032..588a27e011c9f64a0b4a15f93723e74bcefc5de8 100644 (file)
@@ -195,7 +195,6 @@ FilmViewer::set_film (shared_ptr<Film> film)
           in the preview.
        */
        _player->set_always_burn_subtitles (true);
-       _player->set_ignore_audio ();
        _player->set_play_referenced ();
 
        _film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1));
@@ -252,8 +251,6 @@ FilmViewer::refresh_panel ()
 void
 FilmViewer::get ()
 {
-       cout << "get!\n";
-
        pair<shared_ptr<PlayerVideo>, DCPTime> video;
        do {
                video = _butler->get_video ();
@@ -422,9 +419,9 @@ FilmViewer::check_play_state ()
        }
 
        if (_play_button->GetValue()) {
-               _timer.Start (1000 / _film->video_frame_rate());
+               start ();
        } else {
-               _timer.Stop ();
+               stop ();
        }
 }