From 90c782a16c26fa8bfded51cad2bc7bbc14d8f986 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 8 Mar 2017 00:11:50 +0000 Subject: [PATCH] Seemingly basically working butler for video. --- src/lib/butler.cc | 59 +++++++++++++++++++++++++++++------ src/lib/butler.h | 2 ++ src/lib/player.cc | 6 ++++ src/lib/video_ring_buffers.cc | 11 +++++-- src/lib/video_ring_buffers.h | 4 +-- src/wx/film_viewer.cc | 2 ++ 6 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/lib/butler.cc b/src/lib/butler.cc index e40ae0b24..1dbad6152 100644 --- a/src/lib/butler.cc +++ b/src/lib/butler.cc @@ -40,7 +40,8 @@ Butler::Butler (weak_ptr film, shared_ptr player) , _pending_seek_accurate (false) , _finished (false) { - _player->Video.connect (bind (&VideoRingBuffers::put, &_video, _1, _2)); + _player_video_connection = _player->Video.connect (bind (&Butler::video, this, _1, _2)); + _player_changed_connection = _player->Changed.connect (bind (&Butler::player_changed, this)); _thread = new boost::thread (bind (&Butler::thread, this)); } @@ -61,21 +62,30 @@ Butler::thread () while (true) { boost::mutex::scoped_lock lm (_mutex); - while (_video.size() > VIDEO_READAHEAD && !_pending_seek_position) { + /* Wait until we have something to do */ + while (_video.size() >= VIDEO_READAHEAD && !_pending_seek_position) { _summon.wait (lm); } + /* Do any seek that has been requested */ if (_pending_seek_position) { _player->seek (*_pending_seek_position, _pending_seek_accurate); _pending_seek_position = optional (); } - while (_video.size() < VIDEO_READAHEAD) { - _arrived.notify_all (); + /* Fill _video. 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. + */ + while (_video.size() < VIDEO_READAHEAD && !_pending_seek_position) { + lm.unlock (); if (_player->pass ()) { _finished = true; + _arrived.notify_all (); break; } + lm.lock (); + _arrived.notify_all (); } } } @@ -84,7 +94,9 @@ pair, DCPTime> Butler::get_video () { boost::mutex::scoped_lock lm (_mutex); - while (_video.size() == 0 && !_finished) { + + /* Wait for data if we have none */ + while (_video.empty() && !_finished) { _arrived.wait (lm); } @@ -92,20 +104,47 @@ Butler::get_video () return make_pair (shared_ptr(), DCPTime()); } - return _video.get (); + pair, DCPTime> const r = _video.get (); + _summon.notify_all (); + return r; } void Butler::seek (DCPTime position, bool accurate) { + boost::mutex::scoped_lock lm (_mutex); _video.clear (); + _finished = false; + _pending_seek_position = position; + _pending_seek_accurate = accurate; + _summon.notify_all (); +} + +void +Butler::video (shared_ptr video, DCPTime time) +{ + { + boost::mutex::scoped_lock lm (_mutex); + if (_pending_seek_position) { + /* Don't store any video while a seek is pending */ + return; + } + } + + _video.put (video, time); +} + +void +Butler::player_changed () +{ + optional t; { boost::mutex::scoped_lock lm (_mutex); - _finished = false; - _pending_seek_position = position; - _pending_seek_accurate = accurate; + t = _video.earliest (); } - _summon.notify_all (); + if (t) { + seek (*t, true); + } } diff --git a/src/lib/butler.h b/src/lib/butler.h index d801d6cf9..e02351b0f 100644 --- a/src/lib/butler.h +++ b/src/lib/butler.h @@ -41,6 +41,7 @@ public: private: void thread (); void video (boost::shared_ptr video, DCPTime time); + void player_changed (); boost::weak_ptr _film; boost::shared_ptr _player; @@ -57,4 +58,5 @@ private: bool _finished; boost::signals2::scoped_connection _player_video_connection; + boost::signals2::scoped_connection _player_changed_connection; }; diff --git a/src/lib/player.cc b/src/lib/player.cc index 844706e4b..a6df63ac0 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -226,10 +226,16 @@ Player::playlist_content_changed (weak_ptr w, int property, bool freque void Player::set_video_container_size (dcp::Size s) { + if (s == _video_container_size) { + return; + } + _video_container_size = s; _black_image.reset (new Image (AV_PIX_FMT_RGB24, _video_container_size, true)); _black_image->make_black (); + + Changed (false); } void diff --git a/src/lib/video_ring_buffers.cc b/src/lib/video_ring_buffers.cc index 254285456..e81605732 100644 --- a/src/lib/video_ring_buffers.cc +++ b/src/lib/video_ring_buffers.cc @@ -60,6 +60,13 @@ VideoRingBuffers::size () const return _data.size (); } +bool +VideoRingBuffers::empty () const +{ + boost::mutex::scoped_lock lm (_mutex); + return _data.empty (); +} + void VideoRingBuffers::clear () { @@ -68,12 +75,12 @@ VideoRingBuffers::clear () } optional -VideoRingBuffers::latest () const +VideoRingBuffers::earliest () const { boost::mutex::scoped_lock lm (_mutex); if (_data.empty ()) { return optional (); } - return _data.back().second; + return _data.front().second; } diff --git a/src/lib/video_ring_buffers.h b/src/lib/video_ring_buffers.h index f728247fe..cf61b90cc 100644 --- a/src/lib/video_ring_buffers.h +++ b/src/lib/video_ring_buffers.h @@ -36,8 +36,8 @@ public: void clear (); Frame size () const; - - boost::optional latest () const; + bool empty () const; + boost::optional earliest () const; private: mutable boost::mutex _mutex; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 8fff21345..5e15b4b07 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -212,6 +212,8 @@ FilmViewer::refresh_panel () void FilmViewer::get () { + cout << "get!\n"; + pair, DCPTime> video; do { video = _butler->get_video (); -- 2.30.2