From 4073923b2c5ccf127c61435cd575542351421f05 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 9 Apr 2017 22:43:56 +0100 Subject: [PATCH] Several fixes to audio. --- src/lib/butler.cc | 18 ++++++++++++++---- src/lib/player.cc | 30 +++++++++++++++++++----------- src/lib/player.h | 6 +++--- src/lib/video_ring_buffers.cc | 3 --- src/wx/film_viewer.cc | 7 ++----- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/lib/butler.cc b/src/lib/butler.cc index 01c1ec4f8..ea195b5d5 100644 --- a/src/lib/butler.cc +++ b/src/lib/butler.cc @@ -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 film, shared_ptr 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 (); } - /* 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 video, DCPTime time) void Butler::audio (shared_ptr 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 diff --git a/src/lib/player.cc b/src/lib/player.cc index a6df63ac0..3c2b3478e 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -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, DCPTime> > audio = _audio_merger.pull (pull_from); for (list, 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 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 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 (); + _last_video_time = optional (); + _last_audio_time = optional (); } } diff --git a/src/lib/player.h b/src/lib/player.h index 6e9c9d7ee..ea07e1fc8 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -139,11 +139,11 @@ private: /** Last PlayerVideo that was emitted */ boost::shared_ptr _last_video; - /** Time of the last thing we emitted, or the last seek time */ - boost::optional _last_time; + /** Time of the last video we emitted, or the last seek time */ + boost::optional _last_video_time; AudioMerger _audio_merger; - DCPTime _last_audio_time; + boost::optional _last_audio_time; class StreamState { public: diff --git a/src/lib/video_ring_buffers.cc b/src/lib/video_ring_buffers.cc index e81605732..a8688a1cd 100644 --- a/src/lib/video_ring_buffers.cc +++ b/src/lib/video_ring_buffers.cc @@ -34,7 +34,6 @@ using boost::optional; void VideoRingBuffers::put (shared_ptr 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(), DCPTime()); } pair, DCPTime> const r = _data.front (); - cout << "get: here we go! " << to_string(r.second) << "\n"; _data.pop_front (); return r; } diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 3d9ec036b..588a27e01 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -195,7 +195,6 @@ FilmViewer::set_film (shared_ptr 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, 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 (); } } -- 2.30.2