/*
- Copyright (C) 2016-2020 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2016-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+
#include "butler.h"
#include "player.h"
#include "util.h"
using std::shared_ptr;
using boost::bind;
using boost::optional;
-using boost::function;
+using std::function;
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 */
/** 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.
)
: _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)
}
}
+
Butler::~Butler ()
{
boost::this_thread::disable_interruption dis;
return (_video.size() < MAXIMUM_VIDEO_READAHEAD) && (_audio.size() < MAXIMUM_AUDIO_READAHEAD);
}
+
void
Butler::thread ()
try
_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.
return r;
}
+
optional<TextRingBuffers::Data>
Butler::get_closed_caption ()
{
return _closed_caption.get ();
}
+
void
Butler::seek (DCPTime position, bool accurate)
{
seek_unlocked (position, accurate);
}
+
void
Butler::seek_unlocked (DCPTime position, bool accurate)
{
_summon.notify_all ();
}
+
void
Butler::prepare (weak_ptr<PlayerVideo> weak_video)
try
_died = true;
}
+
void
Butler::video (shared_ptr<PlayerVideo> video, DCPTime time)
{
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);
}
+
void
Butler::audio (shared_ptr<AudioBuffers> audio, DCPTime time, int frame_rate)
{
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.
return t;
}
+
void
Butler::disable_audio ()
{
_disable_audio = true;
}
+
pair<size_t, string>
Butler::memory_used () const
{
return _video.memory_used();
}
+
void
Butler::player_change (ChangeType type, int property)
{
_summon.notify_all ();
}
+
void
Butler::text (PlayerText pt, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
{
_closed_caption.put (pt, *track, period);
}
+
string
Butler::Error::summary () const
{