summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2018-07-26 20:59:04 +0100
committerCarl Hetherington <cth@carlh.net>2018-07-26 20:59:04 +0100
commit3009a585f5222a83213c786e3c564c740f450d18 (patch)
treeba65c1dc9ca643656160a6b7045f14c185fdd8f8 /src/lib
parent8484d278ec6905502bd1178cc58d8cb7b3c12df0 (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).
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/butler.cc4
-rw-r--r--src/lib/player.cc45
-rw-r--r--src/lib/player.h7
3 files changed, 46 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;