diff options
| author | Carl Hetherington <cth@carlh.net> | 2018-07-26 20:59:04 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2018-07-26 20:59:04 +0100 |
| commit | 3009a585f5222a83213c786e3c564c740f450d18 (patch) | |
| tree | ba65c1dc9ca643656160a6b7045f14c185fdd8f8 | |
| parent | 8484d278ec6905502bd1178cc58d8cb7b3c12df0 (diff) | |
Protect the public API of Player with a mutex, since
seek() and pass() may be called from the Butler thread
ad the same time as other Player methods are called from
the GUI thread (by FilmViewer and ClosedCaptionViewDialog).
| -rw-r--r-- | src/lib/butler.cc | 4 | ||||
| -rw-r--r-- | src/lib/player.cc | 45 | ||||
| -rw-r--r-- | src/lib/player.h | 7 | ||||
| -rw-r--r-- | src/wx/film_viewer.cc | 2 |
4 files changed, 48 insertions, 10 deletions
diff --git a/src/lib/butler.cc b/src/lib/butler.cc index 112778e25..138ee0fbd 100644 --- a/src/lib/butler.cc +++ b/src/lib/butler.cc @@ -198,6 +198,7 @@ Butler::get_video () } pair<shared_ptr<PlayerVideo>, DCPTime> const r = _video.get (); + cout << "BGV " << to_string(r.second) << " " << _video.size() << "\n"; _summon.notify_all (); return r; } @@ -233,6 +234,7 @@ Butler::prepare (weak_ptr<PlayerVideo> weak_video) const void Butler::video (shared_ptr<PlayerVideo> video, DCPTime time) { + cout << "BV: " << to_string(time) << " " << _video.size() << " " << (float(_video.size()) / 24) << "\n"; boost::mutex::scoped_lock lm (_mutex); if (_pending_seek_position) { /* Don't store any video while a seek is pending */ @@ -246,6 +248,7 @@ Butler::video (shared_ptr<PlayerVideo> video, DCPTime time) void Butler::audio (shared_ptr<AudioBuffers> audio) { + cout << "BA: " << audio->frames() << " " << _audio.size() << " " << (float(_audio.size()) / 48000) << "\n"; { boost::mutex::scoped_lock lm (_mutex); if (_pending_seek_position || _disable_audio) { @@ -265,6 +268,7 @@ bool Butler::get_audio (float* out, Frame frames) { bool const underrun = _audio.get (out, _audio_channels, frames); + cout << "BGA: " << frames << " " << _audio.size() << " " << (float(_audio.size()) / 48000) << "\n"; _summon.notify_all (); return underrun; } diff --git a/src/lib/player.cc b/src/lib/player.cc index 8b2ade1dc..f8471c752 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -258,14 +258,18 @@ Player::playlist_content_changed (weak_ptr<Content> w, int property, bool freque void Player::set_video_container_size (dcp::Size s) { - if (s == _video_container_size) { - return; - } + { + boost::mutex::scoped_lock lm (_mutex); + + if (s == _video_container_size) { + return; + } - _video_container_size = s; + _video_container_size = s; - _black_image.reset (new Image (AV_PIX_FMT_RGB24, _video_container_size, true)); - _black_image->make_black (); + _black_image.reset (new Image (AV_PIX_FMT_RGB24, _video_container_size, true)); + _black_image->make_black (); + } Changed (PlayerProperty::VIDEO_CONTAINER_SIZE, false); } @@ -414,6 +418,8 @@ Player::content_time_to_dcp (shared_ptr<const Piece> piece, ContentTime t) const list<shared_ptr<Font> > Player::get_subtitle_fonts () { + /* Does not require a lock on _mutex as it's only called from DCPEncoder */ + if (!_have_valid_pieces) { setup_pieces (); } @@ -436,12 +442,14 @@ Player::get_subtitle_fonts () void Player::set_ignore_video () { + boost::mutex::scoped_lock lm (_mutex); _ignore_video = true; } void Player::set_ignore_text () { + boost::mutex::scoped_lock lm (_mutex); _ignore_text = true; } @@ -449,6 +457,7 @@ Player::set_ignore_text () void Player::set_always_burn_open_subtitles () { + boost::mutex::scoped_lock lm (_mutex); _always_burn_open_subtitles = true; } @@ -456,6 +465,7 @@ Player::set_always_burn_open_subtitles () void Player::set_fast () { + boost::mutex::scoped_lock lm (_mutex); _fast = true; _have_valid_pieces = false; } @@ -463,6 +473,7 @@ Player::set_fast () void Player::set_play_referenced () { + boost::mutex::scoped_lock lm (_mutex); _play_referenced = true; _have_valid_pieces = false; } @@ -470,6 +481,8 @@ Player::set_play_referenced () list<ReferencedReelAsset> Player::get_reel_assets () { + /* Does not require a lock on _mutex as it's only called from DCPEncoder */ + list<ReferencedReelAsset> a; BOOST_FOREACH (shared_ptr<Content> i, _playlist->content ()) { @@ -546,6 +559,8 @@ Player::get_reel_assets () bool Player::pass () { + boost::mutex::scoped_lock lm (_mutex); + if (!_have_valid_pieces) { setup_pieces (); } @@ -680,6 +695,7 @@ Player::pass () list<PlayerText> Player::closed_captions_for_frame (DCPTime time) const { + boost::mutex::scoped_lock _lm (_mutex); return _active_texts[TEXT_CLOSED_CAPTION].get ( DCPTimePeriod(time, time + DCPTime::from_frames(1, _film->video_frame_rate())) ); @@ -972,6 +988,8 @@ Player::subtitle_stop (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, Conte void Player::seek (DCPTime time, bool accurate) { + boost::mutex::scoped_lock lm (_mutex); + if (!_have_valid_pieces) { setup_pieces (); } @@ -1120,18 +1138,25 @@ Player::discard_audio (shared_ptr<const AudioBuffers> audio, DCPTime time, DCPTi void Player::set_dcp_decode_reduction (optional<int> reduction) { - if (reduction == _dcp_decode_reduction) { - return; + { + boost::mutex::scoped_lock lm (_mutex); + + if (reduction == _dcp_decode_reduction) { + return; + } + + _dcp_decode_reduction = reduction; + _have_valid_pieces = false; } - _dcp_decode_reduction = reduction; - _have_valid_pieces = false; Changed (PlayerProperty::DCP_DECODE_REDUCTION, false); } DCPTime Player::content_time_to_dcp (shared_ptr<Content> content, ContentTime t) { + boost::mutex::scoped_lock lm (_mutex); + if (_have_valid_pieces) { setup_pieces (); } diff --git a/src/lib/player.h b/src/lib/player.h index 223db86b3..4a91c4c52 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -73,6 +73,7 @@ public: std::list<boost::shared_ptr<Font> > get_subtitle_fonts (); std::list<ReferencedReelAsset> get_reel_assets (); dcp::Size video_container_size () const { + boost::mutex::scoped_lock lm (_mutex); return _video_container_size; } @@ -141,6 +142,12 @@ private: void do_emit_video (boost::shared_ptr<PlayerVideo> pv, DCPTime time); void emit_audio (boost::shared_ptr<AudioBuffers> data, DCPTime time); + /** Mutex to protect the whole Player state. When it's used for the preview we have + seek() and pass() called from the Butler thread and lots of other stuff called + from the GUI thread. + */ + mutable boost::mutex _mutex; + boost::shared_ptr<const Film> _film; boost::shared_ptr<const Playlist> _playlist; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index ef28018e9..8c1a79113 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -529,6 +529,8 @@ FilmViewer::start () _audio.startStream (); } + cout << "start playback at " << to_string(_video_position) << "\n"; + _playing = true; _dropped = 0; timer (); |
