summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2017-03-08 00:11:50 +0000
committerCarl Hetherington <cth@carlh.net>2017-04-19 23:04:32 +0100
commit90c782a16c26fa8bfded51cad2bc7bbc14d8f986 (patch)
treeb5057fffa855312fa6c82f8c27a077c021d9afaf /src
parent4f9cb03792e85cbb5b4d554ab8ec0a3275fa7524 (diff)
Seemingly basically working butler for video.
Diffstat (limited to 'src')
-rw-r--r--src/lib/butler.cc59
-rw-r--r--src/lib/butler.h2
-rw-r--r--src/lib/player.cc6
-rw-r--r--src/lib/video_ring_buffers.cc11
-rw-r--r--src/lib/video_ring_buffers.h4
-rw-r--r--src/wx/film_viewer.cc2
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<const Film> film, shared_ptr<Player> 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<DCPTime> ();
}
- 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<shared_ptr<PlayerVideo>, 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<PlayerVideo>(), DCPTime());
}
- return _video.get ();
+ pair<shared_ptr<PlayerVideo>, 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<PlayerVideo> 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<DCPTime> 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<PlayerVideo> video, DCPTime time);
+ void player_changed ();
boost::weak_ptr<const Film> _film;
boost::shared_ptr<Player> _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<Content> 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<DCPTime>
-VideoRingBuffers::latest () const
+VideoRingBuffers::earliest () const
{
boost::mutex::scoped_lock lm (_mutex);
if (_data.empty ()) {
return optional<DCPTime> ();
}
- 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<DCPTime> latest () const;
+ bool empty () const;
+ boost::optional<DCPTime> 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<shared_ptr<PlayerVideo>, DCPTime> video;
do {
video = _butler->get_video ();