projects
/
dcpomatic.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Assorted tidying.
[dcpomatic.git]
/
src
/
lib
/
butler.cc
diff --git
a/src/lib/butler.cc
b/src/lib/butler.cc
index 4ab0092c4d0f819bbc625a3d18f66da4a0ec2c9a..5a8e646aa4635556fca90f8791f23e46b6468a9e 100644
(file)
--- a/
src/lib/butler.cc
+++ b/
src/lib/butler.cc
@@
-1,5
+1,5
@@
/*
/*
- Copyright (C) 2016-202
0
Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-202
1
Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
This file is part of DCP-o-matic.
@@
-18,6
+18,7
@@
*/
*/
+
#include "butler.h"
#include "player.h"
#include "util.h"
#include "butler.h"
#include "player.h"
#include "util.h"
@@
-26,23
+27,24
@@
#include "cross.h"
#include "compose.hpp"
#include "exceptions.h"
#include "cross.h"
#include "compose.hpp"
#include "exceptions.h"
-#include
<boost/weak_ptr.hpp>
-#include <boost/shared_ptr.hpp>
+#include
"video_content.h"
+
using std::cout;
using std::pair;
using std::make_pair;
using std::string;
using std::cout;
using std::pair;
using std::make_pair;
using std::string;
-using
boost
::weak_ptr;
-using
boost
::shared_ptr;
+using
std
::weak_ptr;
+using
std
::shared_ptr;
using boost::bind;
using boost::optional;
using boost::bind;
using boost::optional;
-using
boost
::function;
+using
std
::function;
using namespace dcpomatic;
#if BOOST_VERSION >= 106100
using namespace boost::placeholders;
#endif
using namespace dcpomatic;
#if BOOST_VERSION >= 106100
using namespace boost::placeholders;
#endif
+
/** Minimum video readahead in frames */
#define MINIMUM_VIDEO_READAHEAD 10
/** Maximum video readahead in frames; should never be exceeded (by much) unless there are bugs in Player */
/** Minimum video readahead in frames */
#define MINIMUM_VIDEO_READAHEAD 10
/** Maximum video readahead in frames; should never be exceeded (by much) unless there are bugs in Player */
@@
-52,6
+54,7
@@
using namespace boost::placeholders;
/** Maximum audio readahead in frames; should never be exceeded (by much) unless there are bugs in Player */
#define MAXIMUM_AUDIO_READAHEAD (48000 * MAXIMUM_VIDEO_READAHEAD / 24)
/** Maximum audio readahead in frames; should never be exceeded (by much) unless there are bugs in Player */
#define MAXIMUM_AUDIO_READAHEAD (48000 * MAXIMUM_VIDEO_READAHEAD / 24)
+
/** @param pixel_format Pixel format functor that will be used when calling ::image on PlayerVideos coming out of this
* butler. This will be used (where possible) to prepare the PlayerVideos so that calling image() on them is quick.
* @param aligned Same as above for the `aligned' flag.
/** @param pixel_format Pixel format functor that will be used when calling ::image on PlayerVideos coming out of this
* butler. This will be used (where possible) to prepare the PlayerVideos so that calling image() on them is quick.
* @param aligned Same as above for the `aligned' flag.
@@
-69,7
+72,7
@@
Butler::Butler (
)
: _film (film)
, _player (player)
)
: _film (film)
, _player (player)
- , _prepare_work (new boost::asio::io_service::work
(_prepare_service))
+ , _prepare_work (new boost::asio::io_service::work(_prepare_service))
, _pending_seek_accurate (false)
, _suspended (0)
, _finished (false)
, _pending_seek_accurate (false)
, _suspended (0)
, _finished (false)
@@
-89,7
+92,7
@@
Butler::Butler (
/* The butler must hear about things first, otherwise it might not sort out suspensions in time for
get_video() to be called in response to this signal.
*/
/* The butler must hear about things first, otherwise it might not sort out suspensions in time for
get_video() to be called in response to this signal.
*/
- _player_change_connection = _player->Change.connect (bind (&Butler::player_change, this, _1), boost::signals2::at_front);
+ _player_change_connection = _player->Change.connect (bind (&Butler::player_change, this, _1
, _2
), boost::signals2::at_front);
_thread = boost::thread (bind(&Butler::thread, this));
#ifdef DCPOMATIC_LINUX
pthread_setname_np (_thread.native_handle(), "butler");
_thread = boost::thread (bind(&Butler::thread, this));
#ifdef DCPOMATIC_LINUX
pthread_setname_np (_thread.native_handle(), "butler");
@@
-106,6
+109,7
@@
Butler::Butler (
}
}
}
}
+
Butler::~Butler ()
{
boost::this_thread::disable_interruption dis;
Butler::~Butler ()
{
boost::this_thread::disable_interruption dis;
@@
-175,10
+179,13
@@
Butler::should_run () const
return (_video.size() < MAXIMUM_VIDEO_READAHEAD) && (_audio.size() < MAXIMUM_AUDIO_READAHEAD);
}
return (_video.size() < MAXIMUM_VIDEO_READAHEAD) && (_audio.size() < MAXIMUM_AUDIO_READAHEAD);
}
+
void
Butler::thread ()
try
{
void
Butler::thread ()
try
{
+ start_of_thread ("Butler");
+
while (true) {
boost::mutex::scoped_lock lm (_mutex);
while (true) {
boost::mutex::scoped_lock lm (_mutex);
@@
-228,6
+235,7
@@
try
_arrived.notify_all ();
}
_arrived.notify_all ();
}
+
/** @param blocking true if we should block until video is available. If blocking is false
* and no video is immediately available the method will return a 0 PlayerVideo and the error AGAIN.
* @param e if non-0 this is filled with an error code (if an error occurs) or is untouched if no error occurs.
/** @param blocking true if we should block until video is available. If blocking is false
* and no video is immediately available the method will return a 0 PlayerVideo and the error AGAIN.
* @param e if non-0 this is filled with an error code (if an error occurs) or is untouched if no error occurs.
@@
-237,10
+245,21
@@
Butler::get_video (bool blocking, Error* e)
{
boost::mutex::scoped_lock lm (_mutex);
{
boost::mutex::scoped_lock lm (_mutex);
-
if (_suspended || (_video.empty() && !blocking)
) {
+
auto setup_error = [this](Error* e, Error::Code fallback
) {
if (e) {
if (e) {
- e->code = Error::AGAIN;
+ if (_died) {
+ e->code = Error::DIED;
+ e->message = _died_message;
+ } else if (_finished) {
+ e->code = Error::FINISHED;
+ } else {
+ e->code = fallback;
+ }
}
}
+ };
+
+ if (_video.empty() && (_finished || _died || (_suspended && !blocking))) {
+ setup_error (e, Error::AGAIN);
return make_pair(shared_ptr<PlayerVideo>(), DCPTime());
}
return make_pair(shared_ptr<PlayerVideo>(), DCPTime());
}
@@
-250,24
+269,16
@@
Butler::get_video (bool blocking, Error* e)
}
if (_video.empty()) {
}
if (_video.empty()) {
- if (e) {
- if (_died) {
- e->code = Error::DIED;
- e->message = _died_message;
- } else if (_finished) {
- e->code = Error::FINISHED;
- } else {
- e->code = Error::NONE;
- }
- }
+ setup_error (e, Error::NONE);
return make_pair(shared_ptr<PlayerVideo>(), DCPTime());
}
return make_pair(shared_ptr<PlayerVideo>(), DCPTime());
}
-
pair<shared_ptr<PlayerVideo>, DCPTime>
const r = _video.get ();
+
auto
const r = _video.get ();
_summon.notify_all ();
return r;
}
_summon.notify_all ();
return r;
}
+
optional<TextRingBuffers::Data>
Butler::get_closed_caption ()
{
optional<TextRingBuffers::Data>
Butler::get_closed_caption ()
{
@@
-275,6
+286,7
@@
Butler::get_closed_caption ()
return _closed_caption.get ();
}
return _closed_caption.get ();
}
+
void
Butler::seek (DCPTime position, bool accurate)
{
void
Butler::seek (DCPTime position, bool accurate)
{
@@
-283,6
+295,7
@@
Butler::seek (DCPTime position, bool accurate)
seek_unlocked (position, accurate);
}
seek_unlocked (position, accurate);
}
+
void
Butler::seek_unlocked (DCPTime position, bool accurate)
{
void
Butler::seek_unlocked (DCPTime position, bool accurate)
{
@@
-301,11
+314,12
@@
Butler::seek_unlocked (DCPTime position, bool accurate)
_summon.notify_all ();
}
_summon.notify_all ();
}
+
void
Butler::prepare (weak_ptr<PlayerVideo> weak_video)
try
{
void
Butler::prepare (weak_ptr<PlayerVideo> weak_video)
try
{
-
shared_ptr<PlayerVideo>
video = weak_video.lock ();
+
auto
video = weak_video.lock ();
/* If the weak_ptr cannot be locked the video obviously no longer requires any work */
if (video) {
LOG_TIMING("start-prepare in %1", thread_id());
/* If the weak_ptr cannot be locked the video obviously no longer requires any work */
if (video) {
LOG_TIMING("start-prepare in %1", thread_id());
@@
-327,6
+341,7
@@
catch (...)
_died = true;
}
_died = true;
}
+
void
Butler::video (shared_ptr<PlayerVideo> video, DCPTime time)
{
void
Butler::video (shared_ptr<PlayerVideo> video, DCPTime time)
{
@@
-337,11
+352,12
@@
Butler::video (shared_ptr<PlayerVideo> video, DCPTime time)
return;
}
return;
}
- _prepare_service.post (bind
(&Butler::prepare, this, weak_ptr<PlayerVideo>(video)));
+ _prepare_service.post (bind(&Butler::prepare, this, weak_ptr<PlayerVideo>(video)));
_video.put (video, time);
}
_video.put (video, time);
}
+
void
Butler::audio (shared_ptr<AudioBuffers> audio, DCPTime time, int frame_rate)
{
void
Butler::audio (shared_ptr<AudioBuffers> audio, DCPTime time, int frame_rate)
{
@@
-351,9
+367,10
@@
Butler::audio (shared_ptr<AudioBuffers> audio, DCPTime time, int frame_rate)
return;
}
return;
}
- _audio.put (remap
(audio, _audio_channels, _audio_mapping), time, frame_rate);
+ _audio.put (remap(audio, _audio_channels, _audio_mapping), time, frame_rate);
}
}
+
/** Try to get `frames' frames of audio and copy it into `out'. Silence
* will be filled if no audio is available.
* @return time of this audio, or unset if there was a buffer underrun.
/** Try to get `frames' frames of audio and copy it into `out'. Silence
* will be filled if no audio is available.
* @return time of this audio, or unset if there was a buffer underrun.
@@
-361,11
+378,12
@@
Butler::audio (shared_ptr<AudioBuffers> audio, DCPTime time, int frame_rate)
optional<DCPTime>
Butler::get_audio (float* out, Frame frames)
{
optional<DCPTime>
Butler::get_audio (float* out, Frame frames)
{
-
optional<DCPTime>
t = _audio.get (out, _audio_channels, frames);
+
auto
t = _audio.get (out, _audio_channels, frames);
_summon.notify_all ();
return t;
}
_summon.notify_all ();
return t;
}
+
void
Butler::disable_audio ()
{
void
Butler::disable_audio ()
{
@@
-373,6
+391,7
@@
Butler::disable_audio ()
_disable_audio = true;
}
_disable_audio = true;
}
+
pair<size_t, string>
Butler::memory_used () const
{
pair<size_t, string>
Butler::memory_used () const
{
@@
-380,14
+399,25
@@
Butler::memory_used () const
return _video.memory_used();
}
return _video.memory_used();
}
+
void
void
-Butler::player_change (ChangeType type)
+Butler::player_change (ChangeType type
, int property
)
{
{
+ if (property == VideoContentProperty::CROP) {
+ if (type == ChangeType::DONE) {
+ auto film = _film.lock();
+ if (film) {
+ _video.reset_metadata (film, _player->video_container_size());
+ }
+ }
+ return;
+ }
+
boost::mutex::scoped_lock lm (_mutex);
boost::mutex::scoped_lock lm (_mutex);
- if (type == C
HANGE_TYPE_
PENDING) {
+ if (type == C
hangeType::
PENDING) {
++_suspended;
++_suspended;
- } else if (type == C
HANGE_TYPE_
DONE) {
+ } else if (type == C
hangeType::
DONE) {
--_suspended;
if (_died || _pending_seek_position) {
lm.unlock ();
--_suspended;
if (_died || _pending_seek_position) {
lm.unlock ();
@@
-396,7
+426,7
@@
Butler::player_change (ChangeType type)
}
DCPTime seek_to;
}
DCPTime seek_to;
-
DCPTime
next = _video.get().second;
+
auto
next = _video.get().second;
if (_awaiting && _awaiting > next) {
/* We have recently done a player_changed seek and our buffers haven't been refilled yet,
so assume that we're seeking to the same place as last time.
if (_awaiting && _awaiting > next) {
/* We have recently done a player_changed seek and our buffers haven't been refilled yet,
so assume that we're seeking to the same place as last time.
@@
-408,7
+438,7
@@
Butler::player_change (ChangeType type)
seek_unlocked (seek_to, true);
_awaiting = seek_to;
seek_unlocked (seek_to, true);
_awaiting = seek_to;
- } else if (type == C
HANGE_TYPE_
CANCELLED) {
+ } else if (type == C
hangeType::
CANCELLED) {
--_suspended;
}
--_suspended;
}
@@
-416,10
+446,11
@@
Butler::player_change (ChangeType type)
_summon.notify_all ();
}
_summon.notify_all ();
}
+
void
Butler::text (PlayerText pt, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
{
void
Butler::text (PlayerText pt, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
{
- if (type != T
EXT_
CLOSED_CAPTION) {
+ if (type != T
extType::
CLOSED_CAPTION) {
return;
}
return;
}
@@
-428,6
+459,7
@@
Butler::text (PlayerText pt, TextType type, optional<DCPTextTrack> track, DCPTim
_closed_caption.put (pt, *track, period);
}
_closed_caption.put (pt, *track, period);
}
+
string
Butler::Error::summary () const
{
string
Butler::Error::summary () const
{