}
void
-AnalyseAudioJob::audio (shared_ptr<AudioBuffers> b)
+AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b)
{
for (int i = 0; i < b->frames(); ++i) {
for (int j = 0; j < b->channels(); ++j) {
void run ();
private:
- void audio (boost::shared_ptr<AudioBuffers>);
+ void audio (boost::shared_ptr<const AudioBuffers>);
int64_t _done;
int64_t _samples_per_point;
{
public:
/** Call with some audio data */
- virtual void process_audio (boost::shared_ptr<AudioBuffers>) = 0;
+ virtual void process_audio (boost::shared_ptr<const AudioBuffers>) = 0;
};
class TimedAudioSink
{
public:
/** Call with some audio data */
- virtual void process_audio (boost::shared_ptr<AudioBuffers>, double t) = 0;
+ virtual void process_audio (boost::shared_ptr<const AudioBuffers>, double t) = 0;
};
#endif
{
public:
/** Emitted when some audio data is ready */
- boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>)> Audio;
+ boost::signals2::signal<void (boost::shared_ptr<const AudioBuffers>)> Audio;
void connect_audio (boost::shared_ptr<AudioSink>);
};
{
public:
/** Emitted when some audio data is ready */
- boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, double)> Audio;
+ boost::signals2::signal<void (boost::shared_ptr<const AudioBuffers>, double)> Audio;
void connect_audio (boost::shared_ptr<AudioSink>);
void connect_audio (boost::shared_ptr<TimedAudioSink>);
* @param image Frame image.
*/
void
-Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>, double)
+Combiner::process_video (shared_ptr<const Image> image, bool, shared_ptr<Subtitle>, double)
{
- _image = image;
+ _image = image->clone ();
}
/** Process video for the right half of the frame.
* @param sub Subtitle (which will be put onto the whole frame)
*/
void
-Combiner::process_video_b (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub, double t)
+Combiner::process_video_b (shared_ptr<const Image> image, bool, shared_ptr<Subtitle> sub, double t)
{
/* Copy the right half of this image into our _image */
/* XXX: this should probably be in the Image class */
public:
Combiner (boost::shared_ptr<Log> log);
- void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double);
- void process_video_b (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double);
+ void process_video (boost::shared_ptr<const Image> i, bool, boost::shared_ptr<Subtitle> s, double);
+ void process_video_b (boost::shared_ptr<const Image> i, bool, boost::shared_ptr<Subtitle> s, double);
private:
/** The image that we are currently working on */
}
void
-DelayLine::process_audio (shared_ptr<AudioBuffers> data, double t)
+DelayLine::process_audio (shared_ptr<const AudioBuffers> data, double t)
{
if (_seconds > 0) {
t += _seconds;
}
void
-DelayLine::process_video (boost::shared_ptr<Image> image, bool same, boost::shared_ptr<Subtitle> sub, double t)
+DelayLine::process_video (shared_ptr<const Image> image, bool same, boost::shared_ptr<Subtitle> sub, double t)
{
if (_seconds < 0) {
t += _seconds;
public:
DelayLine (boost::shared_ptr<Log> log, double);
- void process_video (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double);
- void process_audio (boost::shared_ptr<AudioBuffers>, double);
+ void process_video (boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>, double);
+ void process_audio (boost::shared_ptr<const AudioBuffers>, double);
private:
double _seconds;
}
void
-Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Subtitle> sub)
+Encoder::process_video (shared_ptr<const Image> image, bool same, boost::shared_ptr<Subtitle> sub)
{
FrameRateConversion frc (_film->source_frame_rate(), _film->dcp_frame_rate());
}
void
-Encoder::process_audio (shared_ptr<AudioBuffers> data)
+Encoder::process_audio (shared_ptr<const AudioBuffers> data)
{
#if HAVE_SWRESAMPLE
/* Maybe sample-rate convert */
* @param same true if i is the same as the last time we were called.
* @param s A subtitle that should be on this frame, or 0.
*/
- void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s);
+ void process_video (boost::shared_ptr<const Image> i, bool same, boost::shared_ptr<Subtitle> s);
/** Call with some audio data */
- void process_audio (boost::shared_ptr<AudioBuffers>);
+ void process_audio (boost::shared_ptr<const AudioBuffers>);
/** Called when a processing run has finished */
virtual void process_end ();
}
void
-Gain::process_audio (shared_ptr<AudioBuffers> b)
+Gain::process_audio (shared_ptr<const AudioBuffers> b)
{
if (_gain != 0) {
float const linear_gain = pow (10, _gain / 20);
public:
Gain (boost::shared_ptr<Log> log, float gain);
- void process_audio (boost::shared_ptr<AudioBuffers>);
+ void process_audio (boost::shared_ptr<const AudioBuffers>);
private:
float _gain;
return _aligned;
}
+shared_ptr<Image>
+SimpleImage::clone () const
+{
+ return shared_ptr<Image> (new SimpleImage (*this));
+}
+
FilterBufferImage::FilterBufferImage (AVPixelFormat p, AVFilterBufferRef* b)
: Image (p)
, _buffer (b)
virtual bool aligned () const = 0;
+ virtual boost::shared_ptr<Image> clone () const = 0;
+
int components () const;
int lines (int) const;
/* Not allowed */
FilterBufferImage (FilterBufferImage const &);
FilterBufferImage& operator= (FilterBufferImage const &);
+ boost::shared_ptr<Image> clone () const {
+ assert (false);
+ }
AVFilterBufferRef* _buffer;
int* _line_size;
int * stride () const;
libdcp::Size size () const;
bool aligned () const;
+ boost::shared_ptr<Image> clone () const;
protected:
void allocate ();
}
void
-Matcher::process_video (boost::shared_ptr<Image> image, bool same, boost::shared_ptr<Subtitle> sub, double t)
+Matcher::process_video (boost::shared_ptr<const Image> image, bool same, boost::shared_ptr<Subtitle> sub, double t)
{
_pixel_format = image->pixel_format ();
_size = image->size ();
}
void
-Matcher::process_audio (boost::shared_ptr<AudioBuffers> b, double t)
+Matcher::process_audio (boost::shared_ptr<const AudioBuffers> b, double t)
{
_channels = b->channels ();
Matcher::repeat_last_video ()
{
if (!_last_image) {
- _last_image.reset (new SimpleImage (_pixel_format.get(), _size.get(), true));
- _last_image->make_black ();
+ shared_ptr<Image> im (new SimpleImage (_pixel_format.get(), _size.get(), true));
+ im->make_black ();
+ _last_image = im;
}
Video (_last_image, true, _last_subtitle);
{
public:
Matcher (boost::shared_ptr<Log> log, int sample_rate, float frames_per_second);
- void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double);
- void process_audio (boost::shared_ptr<AudioBuffers>, double);
+ void process_video (boost::shared_ptr<const Image> i, bool, boost::shared_ptr<Subtitle> s, double);
+ void process_audio (boost::shared_ptr<const AudioBuffers>, double);
void process_end ();
private:
boost::optional<int> _channels;
struct AudioRecord {
- AudioRecord (boost::shared_ptr<AudioBuffers> a, double t)
+ AudioRecord (boost::shared_ptr<const AudioBuffers> a, double t)
: audio (a)
, time (t)
{}
- boost::shared_ptr<AudioBuffers> audio;
+ boost::shared_ptr<const AudioBuffers> audio;
double time;
};
std::list<AudioRecord> _pending_audio;
boost::optional<double> _first_input;
- boost::shared_ptr<Image> _last_image;
+ boost::shared_ptr<const Image> _last_image;
boost::shared_ptr<Subtitle> _last_subtitle;
bool _had_first_video;
}
void
-Trimmer::process_video (shared_ptr<Image> image, bool same, shared_ptr<Subtitle> sub)
+Trimmer::process_video (shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub)
{
if (_video_in >= _video_start && _video_in <= _video_end) {
Video (image, same, sub);
}
void
-Trimmer::process_audio (shared_ptr<AudioBuffers> audio)
+Trimmer::process_audio (shared_ptr<const AudioBuffers> audio)
{
int64_t offset = _audio_start - _audio_in;
if (offset > audio->frames()) {
_audio_in += audio->frames ();
if (offset != 0 || length != audio->frames ()) {
- audio->move (offset, 0, length);
- audio->set_frames (length);
+ shared_ptr<AudioBuffers> copy (new AudioBuffers (audio));
+ copy->move (offset, 0, length);
+ copy->set_frames (length);
+ audio = copy;
}
Audio (audio);
public:
Trimmer (boost::shared_ptr<Log>, int, int, int, int, float, int);
- void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s);
- void process_audio (boost::shared_ptr<AudioBuffers>);
+ void process_video (boost::shared_ptr<const Image> i, bool, boost::shared_ptr<Subtitle> s);
+ void process_audio (boost::shared_ptr<const AudioBuffers>);
private:
friend class trimmer_test;
#include "i18n.h"
-using namespace std;
-using namespace boost;
+using std::cout;
+using std::string;
+using std::stringstream;
+using std::list;
+using std::ostream;
+using std::vector;
+using std::ifstream;
+using std::istream;
+using std::min;
+using std::max;
+using std::multimap;
+using std::pair;
+using boost::shared_ptr;
+using boost::lexical_cast;
+using boost::optional;
using libdcp::Size;
-thread::id ui_thread;
+boost::thread::id ui_thread;
/** Convert some number of seconds to a string representation
* in hours, minutes and seconds.
stringstream hms;
hms << h << N_(":");
hms.width (2);
- hms << setfill ('0') << m << N_(":");
+ hms << std::setfill ('0') << m << N_(":");
hms.width (2);
- hms << setfill ('0') << s;
+ hms << std::setfill ('0') << s;
return hms.str ();
}
if (strings) {
for (i = 0; i < size && (levels == 0 || i < size_t(levels)); i++) {
- out << N_(" ") << demangle (strings[i]) << endl;
+ out << N_(" ") << demangle (strings[i]) << "\n";
}
free (strings);
Filter::setup_filters ();
SoundProcessor::setup_sound_processors ();
- ui_thread = this_thread::get_id ();
+ ui_thread = boost::this_thread::get_id ();
}
#ifdef DVDOMATIC_WINDOWS
stringstream s;
for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
- s << hex << setfill('0') << setw(2) << ((int) digest[i]);
+ s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]);
}
return s.str ();
string
md5_digest (string file)
{
- ifstream f (file.c_str(), ios::binary);
+ ifstream f (file.c_str(), std::ios::binary);
if (!f.good ()) {
throw OpenFileError (file);
}
- f.seekg (0, ios::end);
+ f.seekg (0, std::ios::end);
int bytes = f.tellg ();
- f.seekg (0, ios::beg);
+ f.seekg (0, std::ios::beg);
int const buffer_size = 64 * 1024;
char buffer[buffer_size];
stringstream s;
for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
- s << hex << setfill('0') << setw(2) << ((int) digest[i]);
+ s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]);
}
return s.str ();
}
/* Pick the best one, bailing early if we hit an exact match */
- float error = numeric_limits<float>::max ();
- boost::optional<FrameRateCandidate> best;
+ float error = std::numeric_limits<float>::max ();
+ optional<FrameRateCandidate> best;
list<FrameRateCandidate>::iterator i = candidates.begin();
while (i != candidates.end()) {
, _socket (_io_service)
, _timeout (timeout)
{
- _deadline.expires_at (posix_time::pos_infin);
+ _deadline.expires_at (boost::posix_time::pos_infin);
check ();
}
void
Socket::check ()
{
- if (_deadline.expires_at() <= asio::deadline_timer::traits_type::now ()) {
+ if (_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now ()) {
_socket.close ();
- _deadline.expires_at (posix_time::pos_infin);
+ _deadline.expires_at (boost::posix_time::pos_infin);
}
_deadline.async_wait (boost::bind (&Socket::check, this));
* @param endpoint End-point to connect to.
*/
void
-Socket::connect (asio::ip::basic_resolver_entry<asio::ip::tcp> const & endpoint)
+Socket::connect (boost::asio::ip::basic_resolver_entry<boost::asio::ip::tcp> const & endpoint)
{
- _deadline.expires_from_now (posix_time::seconds (_timeout));
- system::error_code ec = asio::error::would_block;
- _socket.async_connect (endpoint, lambda::var(ec) = lambda::_1);
+ _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
+ boost::system::error_code ec = boost::asio::error::would_block;
+ _socket.async_connect (endpoint, boost::lambda::var(ec) = boost::lambda::_1);
do {
_io_service.run_one();
- } while (ec == asio::error::would_block);
+ } while (ec == boost::asio::error::would_block);
if (ec || !_socket.is_open ()) {
throw NetworkError (_("connect timed out"));
void
Socket::write (uint8_t const * data, int size)
{
- _deadline.expires_from_now (posix_time::seconds (_timeout));
- system::error_code ec = asio::error::would_block;
+ _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
+ boost::system::error_code ec = boost::asio::error::would_block;
- asio::async_write (_socket, asio::buffer (data, size), lambda::var(ec) = lambda::_1);
+ boost::asio::async_write (_socket, boost::asio::buffer (data, size), boost::lambda::var(ec) = boost::lambda::_1);
do {
_io_service.run_one ();
- } while (ec == asio::error::would_block);
+ } while (ec == boost::asio::error::would_block);
if (ec) {
throw NetworkError (ec.message ());
void
Socket::read (uint8_t* data, int size)
{
- _deadline.expires_from_now (posix_time::seconds (_timeout));
- system::error_code ec = asio::error::would_block;
+ _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
+ boost::system::error_code ec = boost::asio::error::would_block;
- asio::async_read (_socket, asio::buffer (data, size), lambda::var(ec) = lambda::_1);
+ boost::asio::async_read (_socket, boost::asio::buffer (data, size), boost::lambda::var(ec) = boost::lambda::_1);
do {
_io_service.run_one ();
- } while (ec == asio::error::would_block);
+ } while (ec == boost::asio::error::would_block);
if (ec) {
throw NetworkError (ec.message ());
}
}
+/* XXX: it's a shame that this is a copy-and-paste of the above;
+ probably fixable with c++0x.
+*/
+AudioBuffers::AudioBuffers (boost::shared_ptr<const AudioBuffers> other)
+ : _channels (other->_channels)
+ , _frames (other->_frames)
+ , _allocated_frames (other->_frames)
+{
+ _data = new float*[_channels];
+ for (int i = 0; i < _channels; ++i) {
+ _data[i] = new float[_frames];
+ memcpy (_data[i], other->_data[i], _frames * sizeof (float));
+ }
+}
+
/** AudioBuffers destructor */
AudioBuffers::~AudioBuffers ()
{
void
ensure_ui_thread ()
{
- assert (this_thread::get_id() == ui_thread);
+ assert (boost::this_thread::get_id() == ui_thread);
}
/** @param v Source video frame.
public:
AudioBuffers (int channels, int frames);
AudioBuffers (AudioBuffers const &);
+ AudioBuffers (boost::shared_ptr<const AudioBuffers>);
~AudioBuffers ();
float** data () const {
* @param same true if i is the same as last time we were called.
* @param s A subtitle that should be on this frame, or 0.
*/
- virtual void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s) = 0;
+ virtual void process_video (boost::shared_ptr<const Image> i, bool same, boost::shared_ptr<Subtitle> s) = 0;
};
class TimedVideoSink
* @param s A subtitle that should be on this frame, or 0.
* @param t Source timestamp.
*/
- virtual void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s, double t) = 0;
+ virtual void process_video (boost::shared_ptr<const Image> i, bool same, boost::shared_ptr<Subtitle> s, double t) = 0;
};
#endif
* Second parameter is true if the image is the same as the last one that was emitted.
* Third parameter is either 0 or a subtitle that should be on this frame.
*/
- boost::signals2::signal<void (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>)> Video;
+ boost::signals2::signal<void (boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>)> Video;
void connect_video (boost::shared_ptr<VideoSink>);
};
* Third parameter is either 0 or a subtitle that should be on this frame.
* Fourth parameter is the source timestamp of this frame.
*/
- boost::signals2::signal<void (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double)> Video;
+ boost::signals2::signal<void (boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>, double)> Video;
void connect_video (boost::shared_ptr<VideoSink>);
void connect_video (boost::shared_ptr<TimedVideoSink>);
static int frame = 0;
void
-process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub)
+process_video (shared_ptr<const Image> image, bool, shared_ptr<Subtitle> sub)
{
shared_ptr<DCPVideoFrame> local (
new DCPVideoFrame (
return;
}
- boost::shared_ptr<Image> input = _raw_frame;
+ boost::shared_ptr<const Image> input = _raw_frame;
pair<string, string> const s = Filter::ffmpeg_strings (_film->filters());
if (!s.second.empty ()) {
}
void
-FilmViewer::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub, double t)
+FilmViewer::process_video (shared_ptr<const Image> image, bool, shared_ptr<Subtitle> sub, double t)
{
_raw_frame = image;
_raw_sub = sub;
void slider_moved (wxScrollEvent &);
void play_clicked (wxCommandEvent &);
void timer (wxTimerEvent &);
- void process_video (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double);
+ void process_video (boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>, double);
void calculate_sizes ();
void check_play_state ();
void update_from_raw ();
wxTimer _timer;
Decoders _decoders;
- boost::shared_ptr<Image> _raw_frame;
+ boost::shared_ptr<const Image> _raw_frame;
boost::shared_ptr<Subtitle> _raw_sub;
- boost::shared_ptr<Image> _display_frame;
+ boost::shared_ptr<const Image> _display_frame;
/* The x offset at which we display the actual film content; this corresponds
to the film's padding converted to our coordinates.
*/
}
}
-shared_ptr<Image> trimmer_test_last_video;
-shared_ptr<AudioBuffers> trimmer_test_last_audio;
+shared_ptr<const Image> trimmer_test_last_video;
+shared_ptr<const AudioBuffers> trimmer_test_last_audio;
void
-trimmer_test_video_helper (shared_ptr<Image> image, bool, shared_ptr<Subtitle>)
+trimmer_test_video_helper (shared_ptr<const Image> image, bool, shared_ptr<Subtitle>)
{
trimmer_test_last_video = image;
}
void
-trimmer_test_audio_helper (shared_ptr<AudioBuffers> audio)
+trimmer_test_audio_helper (shared_ptr<const AudioBuffers> audio)
{
trimmer_test_last_audio = audio;
}